Referencia de capas con BrainScript
CNTK predefinir una serie de "capas" comunes, lo que facilita la escritura de redes sencillas que constan de capas estándar superpuestas entre sí.
Las capas son objetos de función que se pueden usar como funciones normales de BrainScript, pero contienen parámetros aprendibles y tienen un par adicional de para pasar parámetros o atributos de {}
construcción.
Por ejemplo, esta es la descripción de red de un modelo de capa oculta simple mediante la DenseLayer{}
capa:
h = DenseLayer {1024, activation=ReLU} (features)
p = DenseLayer {9000, activation=Softmax} (h)
que, por ejemplo, se puede usar para entrenar con un criterio de entropía cruzada:
ce = CrossEntropy (labels, p)
Si la red es una concatenación directa de las operaciones (muchas son), puede usar la alternativa.
Sequential()
Notación:
myModel = Sequential (
DenseLayer {1024, activation=ReLU} :
DenseLayer {9000, activation=Softmax}
)
e invoquelo de esta manera:
p = myModel (features)
Modelos de ejemplo
A continuación se muestra un etiquetador de ranura que inserta una secuencia de palabras, lo procesa con un LSTM recurrente y, a continuación, clasifica cada palabra:
taggingModel = Sequential (
EmbeddingLayer {150} : # embed into a 150-dimensional vector
RecurrentLSTMLayer {300} : # forward LSTM
DenseLayer {labelDim} # word-wise classification
)
Y lo siguiente es una red convolucional sencilla para el reconocimiento de imágenes:
convNet = Sequential (
# 3 layers of convolution and dimension reduction by pooling
ConvolutionalLayer {32, (5:5), pad=true, activation=ReLU} :
MaxPoolingLayer {(3:3), stride=(2:2)} :
ConvolutionalLayer {32, (5:5), pad=true, activation=ReLU} :
MaxPoolingLayer {(3:3), stride=(2:2)} :
ConvolutionalLayer {64, (5:5), pad=true, activation=ReLU} :
MaxPoolingLayer {(3:3), stride=(2:2)} :
# 2 dense layers for classification
DenseLayer {64, activation=ReLU} :
LinearLayer {10}
)
Uso compartido de parámetros
Si asigna una capa a una variable y la usa en varios lugares, se compartirán los parámetros. Si dices
lay = DenseLayer {1024, activation=Sigmoid}
h1 = lay (x)
h2 = lay (h1) # same weights as `h1`
h1
y h2
compartirán los mismos parámetros, como lay()
es la misma función en ambos casos.
En el caso anterior, es probable que esto no sea lo que se desea, así que tenga en cuenta.
Si ambas invocaciones anteriores lay()
están pensadas para tener parámetros diferentes, recuerde definir dos instancias independientes, por ejemplo lay1 = DenseLayer{...}
y lay2 = DenseLayer{...}
.
¿Por qué este comportamiento?
Las capas permiten compartir parámetros entre secciones de un modelo.
Considere un modelo DSSM que procesa dos imágenes de entrada, por ejemplo doc
, y query
idénticamente con la misma cadena de procesamiento, y compara los vectores ocultos resultantes:
imageToVec = Sequential (
ConvolutionalLayer {32, (5:5), pad = true, activation = ReLU} :
MaxPoolingLayer {(3:3), stride = (2:2)} :
ConvolutionalLayer {64, (5:5), pad = true, activation = ReLU} :
MaxPoolingLayer {(3:3), stride = (2:2)} :
DenseLayer {64, activation = ReLU} :
LinearLayer {10}
)
zDoc = imageToVec (doc)
zQuery = imageToVec (query) # same model as for zDoc
sim = CosDistance (zdoc, zQuery)
donde imageToVec
es la parte del modelo que convierte imágenes en vector plano.
imageToVec
es un objeto de función que, a su vez, contiene varios objetos de función (por ejemplo, tres instancias de ConvolutionalLayer{}
).
imageToVec
se crea una instancia una vez y esta instancia contiene los parámetros aprendibles de todos los objetos de función incluidos. Ambas invocaciones de model()
compartirán estos parámetros en la aplicación y sus degradados serán la suma de ambas invocaciones.
Por último, tenga en cuenta que si en el ejemplo query
anterior y doc
deben tener las mismas dimensiones, ya que se procesan a través del mismo objeto de función, y esa primera capa del objeto de función tiene su dimensión de entrada inferida para que coincida con la de query
y doc
.
Si sus dimensiones difieren, esta red tiene un formato incorrecto y se producirá un error en la inferencia o validación de dimensiones con un mensaje de error.
Nota de implementación
Muchas capas son contenedores alrededor de primitivos de CNTK subyacentes, junto con los respectivos parámetros aprendibles necesarios. Por ejemplo, ConvolutionalLayer{}
ajusta el Convolution()
primitivo.
Las ventajas de usar capas son:
- las capas contienen parámetros aprendibles de la dimensión correcta
- las capas se pueden componer (cf.
Sequential()
)
DenseLayer, LinearLayer{}{}
Función factory para crear una capa totalmente conectada.
DenseLayer{}
toma con una no linealidad opcional.
DenseLayer {outDim, activation=Identity, init='glorotUniform', initValueScale=1, bias=true}
LinearLayer {outDim, init='glorotUniform', initValueScale=1, bias=true}
Parámetros
-
outDim
: dimensión de salida de esta capa -
activation
(DenseLayer{}
solo): pase una función aquí para usarse como función de activación, comoactivation=ReLU
-
init
('heNormal'
|'glorotUniform'
|...): tipo de inicialización para los pesos. Consulte aquí una lista completa de las opciones de inicialización. -
initValueScale
: la inicialización aleatoria de varianza se multiplica con esto. -
bias
: si es false, no incluya un parámetro de sesgo.
Valor devuelto
Función que implementa la capa totalmente conectada deseada. Consulte la descripción.
Descripción
Use estas funciones de fábrica para crear una capa totalmente conectada.
Use DenseLayer{}
si desea que se incluya una función de activación; de lo contrario LinearLayer{}
, .
Cada una de estas funciones de fábrica crea un objeto de función que contiene una matriz de peso aprendiz y, a menos bias=false
que , un sesgo aprendiz. El objeto de función se puede usar como una función, que implementa una de estas fórmulas:
DenseLayer{...} (v) = activation (W * v + b)
LinearLayer{...} (v) = W * v + b
donde W
es una matriz de peso de la dimensión [outDim x (dimension of v)]
, b
es el sesgo de la dimensión [outdim]
y el valor resultante tiene dimensión (o dimensiones de tensor) según lo indicado por outDim
.
Compatibilidad con Tensor
Si la función devuelta se aplica a una entrada de un rango > de tensor 1, por ejemplo, una imagen 2D, W
tendrá la dimensión [outDim x (first dimension of input) x (second dimension of input) x ...]
.
Por otro lado, outDim
puede ser un vector que especifica dimensiones tensor, por ejemplo (10:10)
.
En ese caso, W
tendrá la dimensión [outDim[0] x outDim[1] x ... x (dimension of input)]
y b
tendrá las dimensiones [outDim[0] x outDim[1] x ...]
tensor .
CNTK producto de matriz interpretará estas dimensiones de entrada o salida adicionales como si estuvieran acopladas en un vector largo.
Para más información sobre esto, consulte la documentación de . Times()
Ejemplo:
h = DenseLayer {1024, activation=Sigmoid) (v)
o alternativamente:
Layer = DenseLayer {1024, activation=Sigmoid)
h = Layer (v)
ConvolucionalLayer{}
Crea una capa de convolución con una no linealidad opcional.
ConvolutionalLayer {numOutputChannels, filterShape,
activation = Identity,
init = 'glorotUniform', initValueScale = 1,
stride = 1, pad = false, lowerPad = 0, upperPad = 0,
bias = true}
Parámetros
-
numOutputChannels
: número de canales de salida (número de filtros) -
filterShape
: extensión espacial del filtro, por ejemplo(5:5)
, para un filtro 2D. La dimensión de canal de entrada no se incluirá aquí. -
activation
: no linealidad opcional, por ejemplo,activation=ReLU
-
init
('heNormal'
|'glorotUniform'
|...): tipo de inicialización aleatoria para los pesos. Consulte aquí para obtener una lista completa de las opciones de inicialización aleatoria. -
initValueScale
: la inicialización aleatoria de varianza se multiplica con esto. -
stride
: se incrementa al deslizar el filtro sobre la entrada. Por ejemplo,(2:2)
para reducir las dimensiones en 2 -
pad
: si no se establece (valor predeterminado), el filtro se desplazará sobre el área de entrada "válida", es decir, no se usa ningún valor fuera del área. Sipad
se establece por otro lado, el filtro se aplicará a todas las posiciones de entrada y los valores fuera de la región válida se considerarán cero. -
lowerPad
,upperPad
: especifica explícitamente distintos márgenes para relleno. Los filtros se desplazarán a través de una región válida que esté (virtualmente) aumentada con ceros. Por ejemplo,lowerPad=(1:2)
anexará una columna de ceros y dos filas de ceros. La dimensión de la salida se extiende en consecuencia. -
bias
: si es false, no incluya un parámetro de sesgo.
Valor devuelto
Función que implementa la capa totalmente conectada deseada. Consulte la descripción.
Descripción
Use estas funciones de fábrica para crear una capa de convolución.
La capa resultante aplica una operación de convolución en un tensor N dimensional.
El autor de la llamada especifica la extensión espacial del filtro.
Un conjunto de filtros de una extensión espacial determinada (por ejemplo (5:5)
, ) se correlaciona con cada ubicación de la entrada (por ejemplo, una [640 x 480]
imagen de tamaño).
Suponiendo que el relleno está habilitado (pad
) y los pasos son 1, esto generará una región de salida de la misma dimensión ([640 x 480]
).
Normalmente, se aplican muchos filtros al mismo tiempo.
numOutputChannels
especifica el número, por lo que para cada ubicación de entrada, se genera un vector completo de numOutputChannels
.
En nuestro ejemplo anterior, si se establece numOutputChannels
en 64, en un [640 x 480 x 64]
tensor de tamaño.
Ese último eje se denomina dimensión de canal.
Cuando la convolución se aplica a una entrada con una dimensión de canal, cada filtro también constará de vectores de la dimensión de canal de la entrada.
Por ejemplo, al aplicar la convolución con una extensión de filtro espacial especificada de (5:5)
a una [640 x 480 x 3]
imagen de color de tamaño, cada filtro será un [5 x 5 x 3]
tensor.
Todos los numOutputChannels
filtros apilados juntos se denomina kernel.
En nuestro ejemplo, la forma del kernel será [5 x 5 x 3 x 64]
.
A continuación se resume la relación entre las distintas dimensiones y formas:
input shape : [ (spatial dims) x (#input channels) ]
spatial extent : [ (filterShape) ]
output shape : [ (spatial dims) x x numOutputChannels ]
kernel shape : [ (filterShape) x (#input channels) x numOutputChannels ]
que en nuestro ejemplo son:
input shape : [ 640 x 480 x 3 ]
spatial extent : [ 5 x 5 ]
output shape : [ 640 x 480 x x numOutputChannels ]
kernel shape : [ 5 x 5 x 3 x numOutputChannels ]
Relleno
Si el relleno no está habilitado, la región de salida se reducirá en las ubicaciones de límite a las que no se puede aplicar la extensión de filtro completa. Por ejemplo, aplicar un (5:5)
filtro de extensión a una imagen sin relleno, las 2 filas y columnas más externas de píxeles harían que el filtro se aplicara fuera de los límites.
Por lo tanto, ConvolutionalLayer{}
reducirá las dimensiones en consecuencia.
Una [640 x 480]
imagen convolvida con un (5:5)
filtro sin relleno dejará una [636 x 476]
región de salida de tamaño.
Pasos
Los stride
parámetros especifican el incremento de filtros.
Los valores de paso mayor que uno darán lugar a un submuestreo de la región de salida.
Por ejemplo, el filtrado de una [640 x 480]
imagen con un paso de (2:2)
dará como resultado una [320 x 240]
región de tamaño con relleno y [318 x 238]
sin relleno.
Notas
Esta capa es un contenedor alrededor del Convolution()
primitivo.
El nombre de los parámetros del kernel de filtro como se muestra en la sección de validación del registro finalizará en .W
.
La dimensión no se mostrará actualmente como [ (filterShape) x (#input channels) x numOutputChannels ]
se ha descrito anteriormente, sino [ numOutputChannels x ((product over filter shape) * (#input channels)) ]'.
Ejemplo:
c = ConvolutionalLayer {64, (3:3), pad = true, stride = (1:1), bias=false} (x)
DeconvLayer{}
Crea una capa de desconvolución.
DeconvLayer {numOutputChannels,
filterShape, numInputChannels,
bias = true,
activation = (x=>x),
init = 'glorotUniform',
initValueScale = 0.001,
initBias = 0,
stride = 1, autoPadding = false,
lowerPad = 0, upperPad = 0,
maxTempMemSizeInSamples = 0}
Parámetros
-
numOutputChannels
: número de canales de salida (número de filtros) -
filterShape
: extensión espacial del filtro, por ejemplo(5:5)
, para un filtro 2D. La dimensión de canal de entrada no se incluirá aquí. -
numInputChannels
: número de canales de entrada (número de filtros del volumen de entrada) -
bias
: si es false, no incluya un parámetro de sesgo. -
activation
: no linealidad opcional, por ejemplo,activation=ReLU
-
init
('heNormal'
|'glorotUniform'
|...): tipo de inicialización aleatoria para los pesos. Consulte aquí para obtener una lista completa de las opciones de inicialización aleatoria. -
initValueScale
: la inicialización aleatoria de varianza se multiplica con esto. -
initBias
: el valor inicial del sesgo. -
stride
: se incrementa al deslizar el filtro sobre la entrada. Por ejemplo,(2:2)
para reducir las dimensiones en 2 -
autoPadding
: si no se establece (valor predeterminado), el filtro se desplazará sobre el área de entrada "válida", es decir, no se usa ningún valor fuera del área. SiautoPadding
se establece por otro lado, el filtro se aplicará a todas las posiciones de entrada y los valores fuera de la región válida se considerarán cero. -
lowerPad
,upperPad
: especifica explícitamente distintos márgenes para el relleno del volumen de salida, es decir, los que se usaron para la entrada en la capa convolucional correspondiente. Es importante establecerlos en correspondencia con la capa convolucional para lograr las mismas dimensiones de tensor.
Valor devuelto
Función que implementa la capa totalmente conectada deseada. Consulte la descripción.
Descripción
Use estas funciones de fábrica para crear una capa de desconvolución.
La capa resultante aplica una operación de desconvolución en un tensor N dimensional.
Esta capa es un contenedor alrededor del Convolution()
primitivo con deconv=true
.
Un caso de uso popular para desconvolución es reconstruir una imagen (vea aquí, por ejemplo). Cuando la convolución toma una región de campo receptiva 2D de entrada y calcula la correlación con un filtro 2D, la desconvolución toma un píxel y la distribuye en una región 2D.
Considere una imagen p(.,.), una ubicación de píxeles (x,y) y un filtro centrado [3 x 3] con el siguiente contenido (por ahora no hay una dimensión de profundidad de mapa de características por ahora, es decir, un único canal):
[ . . c
a b .
. . . ]
Aquí, un b y c son pesos del filtro, '.' Corresponde a un peso cero. Convolución() calcula el píxel de salida q(x, y) en la ubicación (x, y) como:
q(x,y) = b * p(x,y) + a * p(x-1,y) + c * p(x+1,y-1)
La desconvolución toma píxeles q(x,y) y las distribuye a través de una región alrededor (x,y). Si usamos el mismo filtro, realizaría las siguientes contribuciones a la salida r(x,y):
r(x,y) += b * q(x,y)
r(x-1,y) += a * q(x,y)
r(x+1,y-1) += c * q(x,y)
Sabiendo que lo mismo se aplica a todas las x e y en el plano, podemos expresar esto para r(x,y):
r(x,y) += b * q(x,y)
r(x,y) += a * q(x+1,y)
r(x,y) += c * q(x-1,y+1)
o en total,
r(x,y) = b * q(x,y) + a * q(x+1,y) + c * q(x-1,y+1)
Tiene la misma forma que la convolución anterior, excepto que el filtro se refleja a lo largo de ambos ejes.
Ahora presentamos mapas de características en la combinación. Esto es fácil: en lugar de pasar de la profundidad de entrada a la profundidad de salida, vamos a la otra dirección.
En resumen, Convolución (W, x) == Deconvolución (W', x), donde
W : [W x H x C x K]
y
W’ = W
con sus valores reorganizados como: [(W mirrored) x (H mirrored) x K x C]
Es decir, lo que Deconvolución() hace implícitamente es:
- intercambiar las dos dimensiones de profundidad (transponer)
- las dimensiones espaciales (invierten el orden de los datos)
- Convolución() con estos
Ejemplo:
deconv_A = DeconvLayer {inputDim, (5:5), cMap1, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_A)
Consulte Codificador automático de imágenes mediante Deconvolución y Unpooling para obtener un ejemplo detallado y recorrerlo.
MaxPoolingLayer, AveragePoolingLayer{}{}
Funciones de fábrica para crear una capa de agrupación máxima o media.
MaxPoolingLayer {poolShape, stride = 1, pad = false, lowerPad = 0, upperPad = 0}
AveragePoolingLayer {poolShape, stride = 1, pad = false, lowerPad = 0, upperPad = 0} =
Parámetros
-
poolShape
: la forma de la región que se va a agrupar, por ejemplo.(2:2)
-
stride
: se incrementa al deslizar el grupo sobre la entrada. Por ejemplo,(2:2)
para reducir las dimensiones en 2 -
pad
: si no se establece (valor predeterminado), el grupo se desplazará sobre el área de entrada "válida", es decir, no se usa ningún valor fuera del área. Sipad
se establece por otro lado, el grupo se aplicará a todas las posiciones de entrada y los valores fuera de la región válida se considerarán cero. En el caso de la agrupación media, el recuento de promedio no incluye valores rellenados. -
lowerPad
,upperPad
: especifica explícitamente distintos márgenes para relleno. Los filtros se desplazarán a través de una región válida que esté (virtualmente) aumentada con ceros. Por ejemplo,lowerPad=(1:2)
anexará una columna de ceros y dos filas de ceros. La dimensión de la salida se extiende en consecuencia.
Valor devuelto
Función que implementa la capa de agrupación deseada. Consulte la descripción.
Descripción
Use esta función de fábrica para crear una operación de agrupación. Use MaxPoolingLayer{}
para calcular el máximo sobre los valores del área del grupo y AveragePoolingLayer{}
para tomar su promedio.
La operación de agrupación desliza una "ventana del grupo" en las ubicaciones de una región de entrada y calcula el máximo o el promedio de los valores de la región del grupo correspondiente.
Esta operación es estructuralmente muy similar a la convolución, salvo que la operación aplicada a la ventana deslizante es de una naturaleza diferente.
Todas las consideraciones relacionadas con las dimensiones de entrada, el relleno y los pasos se aplican de forma idéntica, por lo que consulte ConvolutionalLayer{}
para obtener más detalles.
Ejemplo:
p = MaxPoolingLayer {(3:3), stride=(2:2)} (c)
MaxUnpoolingLayer{}
Crea una capa máxima de desoling.
MaxUnpoolingLayer {poolShape,
stride = 1, pad = false,
lowerPad = 0, upperPad = 0}
Parámetros
-
poolShape
: forma de la región que se va a desagrupar (el tamaño de la región de salida ), por ejemplo,(2:2)
-
stride
: se incrementa al deslizar el grupo sobre la salida. Por ejemplo,(2:2)
para aumentar las dimensiones en 2 -
pad
: si no se establece (valor predeterminado), el grupo se desplazará sobre el área de salida "válida", es decir, no se usa ningún valor fuera del área. -
lowerPad
,upperPad
: especifica explícitamente distintos márgenes para relleno. Los filtros asumen una región de salida válida que está aumentada (virtualmente).
Valor devuelto
Función que implementa la capa de desagrupación deseada. Consulte la descripción.
Descripción
Use esta función de generador para crear una operación de desagrupación.
La operación de desagrupación es la inversa de una operación de agrupación. Requiere dos entradas: la salida de su capa de agrupación correspondiente, por ejemplo p1
, y la entrada de su capa de agrupación correspondiente, por ejemplo r1
, también. Desliza una "ventana de grupo inversa" en las ubicaciones de su entrada p1
y proyecta el valor en esa posición de la región de salida que tenía el valor máximo en la operación de agrupación correspondiente, es decir, en r1
. La segunda entrada r1
es necesaria en CNTK para determinar el destino de la operación Desagrupación, ya que CNTK no almacena las variables de modificador llamadas (consulte aquí para obtener más información).
Ejemplo:
unpool_A = MaxUnpoolingLayer {(2:2), stride=(2:2)}(deconv_B, relu_A)
Consulte Codificador automático de imágenes mediante Deconvolución y Unpooling para obtener un ejemplo detallado y recorrerlo.
EmbeddingLayer{}
EmbeddingLayer {outDim,
init='glorotUniform', initValueScale=1,
embeddingPath = '', transpose = false}
Parámetros
-
outDim
: la dimensión del vector de inserción deseado. -
init
('heNormal'
|'glorotUniform'
|...): tipo de inicialización para los pesos. Consulte aquí para obtener una lista completa de las opciones de inicialización. -
initValueScale
: la inicialización aleatoria de varianza se multiplica con esto. -
embeddingPath
: si se especifica, las inscrusciones no se aprenden, pero se cargan desde un archivo y no se actualizan aún más durante el entrenamiento. -
transpose
: permite cargar incrustaciones almacenadas en forma transpuesta.
Valor devuelto
Función que implementa la capa de inserción. Consulte la descripción.
Descripción
"Incrustación" hace referencia a la representación de palabras u otros elementos discretos por vectores continuos densos. En esta capa se supone que la entrada está en forma de un solo acceso. Por ejemplo, para un tamaño de vocabulario de 10 000, se espera que cada vector de entrada tenga una dimensión de 10 000 y consta de ceros excepto una posición que contenga 1. El índice de esa ubicación es el índice de la palabra o elemento que representa.
En CNTK, los vectores de inserción correspondientes se almacenan como columnas de una matriz. Por lo tanto, la asignación de una palabra de entrada a su inserción se implementa como un producto de matriz. Para que esto sea muy eficaz, es importante que los vectores de entrada se almacenen en formato disperso.
Hecho divertido: el degradado de una matriz de incrustación tiene la forma de vectores de degradado que solo son distintos de cero para las palabras que se ven en un minibatch. Dado que para vocabularios realistas de decenas o cientos de miles, la gran mayoría de las columnas sería cero, CNTK implementa tiene una optimización específica para representar el degradado en forma "dispersa de columna".
Problema conocido: la forma de degradado dispersa de columna mencionada anteriormente no es compatible actualmente con nuestra técnica de paralelización SGD de 1 bits . En su lugar, use la técnica block-momentum .
Ejemplo
Inserción aprendida que representa palabras de un vocabulario de 87636 como vector de 300 dimensiones:
input = Input{87636, sparse=true} # word sequence, as one-hot vector, sparse format
embEn = EmbeddingLayer{300} (input) # embed word as a 300-dimensional continuous vector
Además sparse=true
de , también se debe declarar una entrada como dispersa en el bloque de reader
configuración.
Este es un ejemplo de lectura de la entrada de texto dispersa con :CNTKTextFormatReader
reader = {
readerType = "CNTKTextFormatReader"
file = "en2fr.txt"
randomize = true
input = {
input = { alias = "E" ; dim = 87636 ; format = "sparse" }
labels = { alias = "F" ; dim = 98624 ; format = "sparse" }
}
}
Si, en su lugar, los vectores de inserción ya existen y deben cargarse desde un archivo, tendría el siguiente aspecto:
input = Input{87636, sparse=true} # word sequence, as one-hot vector, sparse format
embEn = EmbeddingLayer{300, embeddingPath="embedding-en.txt", transpose=true} (w) # embedding from disk
donde se espera que el archivo "embedding-en.txt"
conste de 87 636 filas de texto, cada una de las cuales consta de 300 números separados por espacios.
Dado que este archivo guarda las incrustaciones como filas en lugar de columnas, transpose=true
transponerá la matriz sobre la marcha.
RecurrenteLSTMLayer{}, RecurrenteLSTMLayerStack{}
Funciones de fábrica para crear un LSTM recurrente de una sola capa o de varias capas.
RecurrentLSTMLayer {outDim, cellShape = None,
goBackwards = false,
usePeepholes = false,
init = 'glorotUniform', initValueScale = 1,
enableSelfStabilization = false,
allowOptimizedEngine = false}
RecurrentLSTMLayerStack {layerDims,
cellShapes = None,
usePeepholes = false,
init = 'glorotUniform', initValueScale = 1,
enableSelfStabilization = false,
allowOptimizedEngine = false}
Parámetros
-
outDim
(RecurrentLSTMLayer{}
): dimensión de la salida de la red. Para indicar un tensor de rango>1, puede ser un vector, por ejemplo.(40:2)
-
layerDims
(RecurrentLSTMLayerStack{}
): matriz de dimensiones de las capas internas y la salida de la red -
cellShape
( (RecurrentLSTMLayer{}
, opcional): la dimensión de la celda LSTM. Normalmente, esto es idéntico aoutDim
. Si se proporciona un valor diferente, se insertará una proyección lineal adicional para convertir de la dimensión de celda a la salida. -
cellShapes
( (RecurrentLSTMLayerStack{}
, opcional): matriz de valores comocellShape
paraRecurrentLSTMLayer()
denotar la proyección -
goBackwards
(opcional): si es true, la periodicidad se ejecuta hacia atrás. -
usePeepholes
(opcional): si es true, use conexiones de agujero en el LSTM. -
init
('heNormal'
|'glorotUniform'
|...): tipo de inicialización para los pesos. Consulte aquí para obtener una lista completa de las opciones de inicialización. -
initValueScale
: la inicialización aleatoria de varianza se multiplica con esto. -
enableSelfStabilization
(opcional): si es true, inserte una operación de "estabilizador" similar aStabilizerLayer{}
-
allowOptimizedEngine
(opcional, valor predeterminado false): si es true, use el motor de RNN optimizado de cuDNN siempre que sea posible.
Valor devuelto
Función que implementa las capas deseadas que se aplican o aplican un LSTM recurrente a su secuencia de entrada. Esta capa (-stack) asigna una secuencia de entrada a una secuencia de estados ocultos de la misma longitud.
Descripción
Esto implementa el LSTM recurrente que se aplicará a una secuencia de entradas, en dos variantes: una sola capa y una pila de varias capas. Esta operación controla automáticamente la entrada de longitud variable. El valor inicial del estado oculto y la celda son 0.
Al aplicar esta capa a una secuencia de entrada, se devolverá la secuencia de los estados ocultos del LSTM recurrente (la parte superior de la pila) (no se devuelve el valor de la celda de memoria de LSTM).
La secuencia devuelta tiene la misma longitud que la entrada.
Si solo se desea el último estado, como en la clasificación de secuencia o en algunos escenarios de secuencia a secuencia, use BS.Sequences.Last()
para extraer solo el estado oculto del último elemento.
(En una periodicidad hacia atrás, usaría BS.Sequences.First()
).
Para crear un modelo bidireccional con RecurrentLSTMLayer()
, use dos capas, una con goBackwards=true
y Splice()
las dos salidas juntas.
RecurrentLSTMLayerStack()
actualmente no admite modelos bidireccionales, debe construirlos manualmente con varios RecurrentLSTMLayer()/Splice()
combos.
Uso del motor de RNN5 de CuDN5
Esta función usará automáticamente el motor RNN optimizado de CuDN5 si es posible, es decir, si es posible.
- el modelo especificado es uno que se puede implementar mediante la función de CuDNN5.
- sin proyección (sin
cellShape
parámetro) - no hay conexiones de orificio de peep
- sin auto-estabilización
- no retroceder
- para
RecurrentLSTMLayerStack{}
, todas las dimensiones de capa tienen el mismo valor
- sin proyección (sin
allowOptimizedEngine=true
En concreto, CNTK requiere habilitar allowOptimizedEngine=true
.
Esto se debe a que el RNN5 de CuDN5 se implementa como una operación primitiva de CNTK que requiere una GPU.
Sin embargo, muchos sistemas reales usan GPU para el entrenamiento, pero solo servidores de CPU en la implementación.
El CuDNN5 RNN no es adecuado aquí.
(Teóricamente es posible usar el RNN5 de CuDNN5 para el entrenamiento y reemplazarlo por una operación de edición con una implementación de LSTM explícita equivalente en BrainScript).
Notas
Si allowOptimizedEngine=true
estas dos variantes de capa son contenedores alrededor del OptimizedRNNStack()
primitivo.
Ejemplo
Un clasificador de texto simple, que ejecuta una secuencia de palabras a través de una periodicidad y, a continuación, pasa el último estado oculto del LSTM a un clasificador softmax, podría tener esta forma:
w = Input{...} # word sequence (one-hot vectors)
e = EmbeddingLayer {150} (w) # embed as a 150-dimensional dense vector
h = RecurrentLSTMLayer {300} (e) # left-to-right LSTM with hidden and cell dim 300
t = BS.Sequences.Last (h) # extract last hidden state
z = DenseLayer {10000, activation=Softmax} (t) # softmax classifier
Para cambiar el ejemplo anterior a una pila de tres capas que usa el motor de RNN5 cuDN5, cambie esta línea:
h = RecurrentLSTMLayerStack {(300:300:300), allowOptimizedEngine=true} (e)
Para crear un LSTM bidireccional bidireccional (por ejemplo, usar la mitad de la dimensión oculta en comparación con arriba), úselo:
hFwd = RecurrentLSTMLayer {150} (e)
hBwd = RecurrentLSTMLayer {150, goBackwards=true} (e)
h = Splice (hFwd:hBwd)
DelayLayer{}
Función factory para crear una capa que retrasa su entrada.
DelayLayer {T=1, defaultHiddenActivation=0}
Parámetros
-
T
: el número de pasos de tiempo que se van a retrasar. Para acceder a los valores futuros, use un valor negativo. -
defaultHiddenActivation
: valor que se va a usar para los fotogramas retrasados en los límites.
Valor devuelto
Función que implementa la operación de retraso deseada.
Descripción
Esta operación retrasa una secuencia de entrada por T
pasos (valor predeterminado 1).
Esto resulta útil, por ejemplo, para convertir una secuencia de palabras en una secuencia de triples de palabras superpuestas.
Considere una secuencia de entrada "a b c b", que se codificará como una secuencia de vectores one-hot de la siguiente manera:
1 0 0 0
0 1 0 1
0 0 1 0
En este caso, cada columna es un vector de un solo acceso y corresponde a una palabra.
La aplicación DelayLayer{T=1}
a esta entrada generará esta secuencia:
0 1 0 0
0 0 1 0
0 0 0 1
Todos los tokens se retrasan en uno y la primera posición se rellena como un vector 0.
Del mismo modo, el uso DelayLayer{T=-1}
de (retraso negativo) dará acceso a los valores futuros y rellenará desde la derecha con un cero:
0 0 0 0
1 0 1 0
0 1 0 0
Notas
Esta capa es un contenedor alrededor de los PastValue()
primitivos y FutureValue()
.
Ejemplo
A continuación se muestra cómo apilar tres palabras vecinas en un vector de trigrama:
x = ... # input value, e.g. a N-dimensional one-hot vector
xp = DelayLayer{} (x) # previous value
xn = DelayLayer{T-1} (x) # next value (negative delay)
tg = Splice (xp : x : xn) # concatenate all into a 3N-dimensional three-hot vector
BatchNormalizationLayer{}, LayerNormalizationLayer{}, StabilizerLayer{}
Funciones de fábrica para crear capas para la normalización por lotes, la normalización de capas y la auto-estabilización.
BatchNormalizationLayer {spatialRank = 0,
normalizationTimeConstant = 5000,
initialScale = 1, epsilon = 0.00001, useCntkEngine = true}
LayerNormalizationLayer {initialScale = 1, initialBias = 0}
StabilizerLayer{}
Parámetros
BatchNormalizationLayer
:
-
spatialRank
: los parámetros de normalización se agrupan sobre las primerasspatialRank
dimensiones. Los valores permitidos actualmente son 0 (sin agrupación) y 2 (agrupación en todas las posiciones de píxeles de una imagen) -
normalizationTimeConstant
(valor predeterminado 5000): constante de tiempo en muestras del filtro de paso bajo de primer orden que se usa para calcular estadísticas de media/varianza para su uso en inferencia -
initialScale
: valor inicial del parámetro de escala -
epsilon
: valor pequeño que se agrega a la estimación de varianza al calcular el inverso -
useCntkEngine
: si es true, use la implementación nativa de CNTK. Si es false, use la implementación de cuDNN (solo GPU).
LayerNormalizationLayer
:
-
initialScale
: valor inicial del parámetro de escala -
initialBias
: valor inicial del parámetro de sesgo
Valor devuelto
Función que implementa una capa que realiza la operación de normalización.
Descripción
BatchNormalizationLayer{}
implementa la técnica descrita en el artículo Normalización por lotes: Aceleración del entrenamiento de redes profundas mediante la reducción del cambio de covariante interno (Sergio Ioffe, Christian Szegedy).
Normaliza sus entradas para cada minibatch por la media/varianza de minibatch, y la des normaliza con un factor de escalado y sesgo aprendidos.
En la inferencia, en lugar de usar la media/varianza de minibatch, la normalización por lotes usa una estimación media/var de ejecución a largo plazo.
Esta estimación se calcula durante el entrenamiento mediante estadísticas de minibatch de filtrado de paso bajo.
El parámetro puede modificar normalizationTimeConstant
la constante de tiempo del filtro de paso bajo.
Se recomienda comenzar con el valor predeterminado de (5000), pero experimentar con otros valores, normalmente en el orden de varios miles a decenas de miles.
LayerNormalizationLayer{}
implementa normalización de capas (Jimmy Lei Ba, Jamie Ryan Kiros, Geoffrey E. Hinton).
Normaliza cada muestra de entrada restando la media en todos los elementos de la muestra y dividiendo por la desviación estándar en todos los elementos de la muestra.
StabilizerLayer{}
implementa un auto-estabilizador por red neuronal profunda auto-estabilizada (P. Ghahremani, J. Droppo).
Esta técnica simple pero eficaz multiplica su entrada con un escalar aprendiz (pero a diferencia de la normalización de capas, no normaliza primero la entrada, ni resta una media).
Tenga en cuenta que, en comparación con el documento original, que propone un escalar beta
lineal o exponencial Exp (beta)
, encontramos que resulta beneficioso usar una operación softplus afilada por la sugerencia del segundo autor, que evita tanto valores negativos como inestabilidad del exponencial.
Notas
BatchNormalizationLayer{}
es un contenedor alrededor del BatchNormalization()
primitivo.
LayerNormalizationLayer{}
y StabilizerLayer{}
se expresan directamente en BrainScript.
Ejemplo
Una capa típica en una red convolucional con normalización por lotes:
MyLayer (x, depth, initValueScale) =
{
c = ConvolutionalLayer {depth, (5:5), pad=true, initValueScale=initValueScale} (x)
b = BatchNormalizationLayer {spatialRank = 2} (c) #####
r = ReLU (b)
p = MaxPoolingLayer {(3:3), stride = (2:2)} (r)
}.p
FeatureMVNLayer{}
Función factory para crear una capa que normaliza la entrada de características por su media y desviación estándar.
FeatureMVNLayer{}
Parámetros
Lista de argumentos {}
vacía.
Valor devuelto
Función que implementa una capa que realiza la operación de normalización.
Descripción
Esta capa normaliza la entrada en una red neuronal por su sesgo y varianza. Estos valores se calculan por adelantado realizando un paso completo a través de los datos de entrenamiento y, a continuación, guardados e inmovilizados. Esto ocurrirá automáticamente.
Dado que los parámetros de esta capa están precalificados en un paso independiente antes del entrenamiento principal, solo se puede aplicar a las variables declaradas como Input{}
.
Ejemplo
Se trata de un principio típico de una red neuronal para el modelado acústico de voz:
features = Input{40} # e.g. speech features
featNorm = FeatureMVNLayer{} (features)
h = DenseLayer{2048} (featNorm)
...