【theano-windows】学习笔记十一——theano中与神经网络相关函数
2017-09-19 16:59
1646 查看
前言
经过softmax和
MLP的学习, 我们发现
thenao.tensor中除了之前的博客【theano-windows】学习笔记五——theano中张量部分函数提到的张量的定义和基本运算外, 还有一个方法称为
nnet, 如果自己实现过前面两篇博客中的代码就会发现用到了
theano.tensor.nnet.sigmoid和
thenao.tensor.nnet.tanh这两个神经网络的激活函数, 那么就应该想了, 这个
nnet是否对于在
theano中实现神经网络很重要呢?所以我就跑去看了一下官网的介绍了, 感觉有必要摘抄一波.
【注】本次学习只是摘抄点感觉常用的函数, 见到陌生的操作可以再去查官方文档
进入官方对
nnet的介绍的界面时, 可以发现有五种操作
conv:卷积神经网络相关操作
nnet:神经网络相关操作
neighbours:卷积网络中图片的处理操作
bn: 批归一化batch normalization
blocksparse: 块稀疏乘法操作(有
gemv和
outer)
国际惯例, 参考博客
Ops related to neural networks
Theano tutorial和卷积神经网络的Theano实现
卷积相关操作
2D卷积函数
theano.tensor.nnet.conv2d(input, filters, input_shape=None, filter_shape=None, border_mode='valid', subsample=(1, 1), filter_flip=True, image_shape=None, **kwargs)#默认翻转卷积核
参数解释:
input: 四维张量符号变量, 维度依次代表(批大小, 输入通道, 输入行, 输入列)
filters: 四维张量符号变量. 维度依次代表(输出通道, 输入通道, 滤波器行, 滤波器列)
input_shape: 可选变量, 可以是
None, 也可以是四个整数或者常量组成的元组或者列表, 代表输入的大小
filter_shape: 可选变量, 可以是
None, 也可以是四个整数或者常量组成的元组或者列表, 用于选择优化实现, 可以指定列表中某个元素为
None, 表示这个元素在编译的时候是未知的
border_mode: 字符串, 整型, 或者两个整型组成的元组-以下任意一种
valid: 输出大小inputshape−flitershape+1
full: 输出大小inputshape+filtershape−1
half: 使用filterrows//2行和filter//colums列对称填充输入边界,然后执行
valid
int: 使用指定的全零宽度向量填充输入的对称边界, 然后使用
valid
(int1,int2): 使用
int1行和
int2列填充输入的对称边界, 然后执行
valid
subsample: 长度为2的元组, 对输出进行下采样, 也称为步长
strides
fliter_flip: 如果为
True, 就在滑动卷积窗口前翻转
filter, 翻转
filter的操作经常称为卷积(convolution),而且这个值经常默认为
True. 如果设置为
False, 那么就不翻转
filter, 这个操作一般叫做互相关(cross-correlation)
*image_shape*: 为
None或者四个整型或者常变量组成的元组或者列表,
input_shape的别名, 已弃用
filter_dilation:长度为2的元组, 对输入进行下采样, 经常称为空洞卷积(dilation),详细看知乎的解释如何理解空洞卷积(dilated convolution)?
*kwargs*: 兼容性, 常被忽略
返回值: 一系列的特征图, 大小是(批大小, 输出通道, 输出行, 输出列)
theano.sandbox.cuda.fftconv.conv2d_fft(input, filters, image_shape=None, filter_shape=None, border_mode='valid', pad_last_dim=False)
简介: 是仅支持
GPU的
nnet.conv2d是实现, 使用了傅里叶变换来实现这个操作, 也会翻转卷积核. 但是
conv2d_fft不能被直接使用, 因为没有提供梯度. 仅仅支持输入的最后一个维度是偶数, 其它的维度任意, 滤波器可以具有偶数或者技术的宽度. 如果你的输入一定具有奇数宽度, 那么可以使用填充的方法来解决, 如果你不确定你的输入倒是是偶数还是技术, 千万不要随便使用填充参数
pad_last_dim, 因为这个参数是无条件的加接一个维度, 可能会让偶数输入变技术, 导致一些问题的发生……..balabalabala后面一堆, 反正意思就是使用它挺麻烦的, 不如直接用
nnet.conv2d了
参数(在valid模式中输入必须大于滤波器)与上面的
conv2d相同, 就是多了一个不一样的:
pad_last_dim: 无条件地对最后一个维度进行填充.返回结果时会删除这个填充的部分
3D卷积
theano.tensor.nnet.conv3d(input, filters, input_shape=None, filter_shape=None, border_mode='valid', subsample=(1, 1, 1), filter_flip=True, filter_dilation=(1, 1, 1))
参数:
input: 五维的符号张量. 每个维度分别代表(批大小, 输入通道, 输入深度, 输入行, 输入列)
filters: 五维的符号张量. 每个维度分别代表(输出通道, 输入通道, 滤波器深度, 滤波器行, 滤波器列)
input_shape: 输入参数大小
filter_shape: 滤波器参数大小
border_mode: 字符串, 整型, 或者两个整型组成的元组-以下任意一种
valid: 输出大小inputshape−flitershape+1
full: 输出大小inputshape+filtershape−1
half: 使用filterrows//2行和filter//colums列对称填充输入边界,然后执行
valid
int: 使用指定的全零宽度向量填充输入的对称边界, 然后使用
valid
(int1,int2,int3): 使用
int1、
int2和’int3’行填充输入的对称边界, 然后执行
valid
subsample: 长度为3的元组, 对输出进行下采样, 也称为步长
strides
fliter_flip: 如果为
True, 就在滑动卷积窗口前翻转
filter的’x,y,z’维度, 翻转
filter的操作经常称为卷积(convolution),而且这个值经常默认为
True. 如果设置为
False, 那么就不翻转
filter, 这个操作一般叫做互相关(cross-correlation)
filter_dilation:长度为3的元组, 对输入进行下采样, 经常称为空洞卷积(dilation)
返回值:卷积得到的特征图, 维度分别代表(批大小, 输出通道, 输出深度, 输出行, 输出列)
theano.sandbox.cuda.fftconv.conv3d_fft(input, filters, image_shape=None, filter_shape=None, border_mode='valid', pad_last_dim=False)
通过快速傅里叶变换
fft执行卷积, 仅仅支持输入的最后一维是偶数. 其它的维度可以任意, 滤波器的最后一维可以是偶数或者奇数.
最后三个维度的语义并不重要, 只要他们在输入和滤波器之间的顺序是一样的就行.比如卷积如果是在图像里面执行的, 那么可以是(duration,height,width)也可以是(height,width,duration)…….剩下的和
conv2d_fft的描述一样, 就是如果你非要输入奇数维度, 请使用填充参数balabalabala………
theano.tensor.nnet.conv3d2d.conv3d(signals, filters, signals_shape=None, filters_shape=None, border_mode='valid')
简介:
conv3d2d是使用
conv2加上数据
reshape实现的三维卷积操作, 某些情况下比
conv3d快, 它在GPU上工作, 并且翻转卷积核. 包含视频的时空卷积
参数:
signals: 像素具有颜色通道的图像的时间序列, 形状是[Ns,Ts,C,Hs,Ws]
filters: 时空滤波器,维度[Nf, Tf, C, Hf, Wf]
signals_shape: 信号的维度
filter_shape: 滤波器的维度
border_mode: 这个与卷积相同, 有
valid,
full,
half
注: 另一种定义
signals的方法是(批, 时间, 输入通道, 行, 列) ; 另一种定义滤波器的方法(输出通道, 时间, 输入通道, 行, 列)
还有一堆其它的函数懒得贴了, 以后遇到了再说
神经网络相关操作
其实就是各种激活函数之类的:sigmoid
sigmoid(x)=11+e−xtheano.tensor.nnet.nnet.sigmoid(x) theano.tensor.nnet.nnet.ultra_fast_sigmoid(x) theano.tensor.nnet.nnet.hard_sigmoid(x) ''' hard_sigmoid: 1.0s ultra_fast_sigmoid: 1.3s sigmoid (with amdlibm): 2.3s sigmoid (without amdlibm): 3.7s '''
softplus
softplus(x)=loge(1+ex)theano.tensor.nnet.nnet.softplus(x) #神经网络中的用法经常如下 x,y,b = T.dvectors('x','y','b') W = T.dmatrix('W') y = T.nnet.softplus(T.dot(W,x) + b)
softsign
softsign=x1+abs(x)theano.tensor.nnet.nnet.softsign(x)
softmax
softmaxij(x)=exij∑kexik有一个小技巧就是这个softmax的计算是稳定的, 因为它采用了如下计算过程:
e_x = exp(x - x.max(axis=1, keepdims=True)) out = e_x / e_x.sum(axis=1, keepdims=True)
也就是说先减去了一个最大值, 随后才采用softmax的标准式子计算属于每个类别的概率(突然想到, 如果之前层用sigmoid激活, 是不是softmax就不需要减去最大值了么?因为sigmoid使得x∈{0,1},而使用
Relu的话, 最好还是减一下, 但是总而言之, 无论是
caffe还是
theano都进行了减最大值操作). 为什么要减?因为如果上一层输出x很大, 那么编译器就会发生上溢出(e1000)或者下溢出(e−1000), 那么减去最大值以后肯定不会上溢出了, 即使发生下溢出, 也会由于取对数而解决此问题. 详细原因请戳这里1,这里2
x,y,b = T.dvectors('x','y','b') W = T.dmatrix('W') y = T.nnet.softmax(T.dot(W,x) + b)
Relu
theano.tensor.nnet.relu(x, alpha=0)
alpha是负值输入的斜率,属于0-1之间, 默认为0(标准的Relu), 如果是
1的话, 激活函数就成线性激活了, 而其它的数就是传说中的
Leaky Relu
因为这个函数比较重要, 所以扩展一下说明它的三种形式
Relu,
LeakyRelu,
PRelu,摘自[Caffe]:关于ReLU、LeakyReLU 、PReLU layer
Relu
forward activation:f(x)=max(0,x)backward gradient:∂E∂x={0, if x≤0∂E∂y,if x>0
Leaky Relu
forward activation:f(x)=max(0,x)+negativeslop∗min(0,x)backward gradient:∂E∂x=⎧⎩⎨v∗∂E∂y, if x≤0∂E∂x, if x>0
Parametric Relu
forward activation:f(xi)=max(0,xi)+ai∗min(0,xi)backward activation:⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪for xi:∂E∂xi=⎧⎩⎨ai∂E∂yi, if xi≤0∂E∂yi, if xi>0for ai:∂E∂ai={∑xixi∂E∂yi, if xi≤00, if xi>0
binary_crossentropy
crossentropy(t,o)=−(t⋅log(o)+(1−t)⋅log(1−o))#theano.tensor.nnet.nnet.binary_crossentropy(output, target) x, y, b, c = T.dvectors('x', 'y', 'b', 'c') W = T.dmatrix('W') V = T.dmatrix('V') h = T.nnet.sigmoid(T.dot(W, x) + b) x_recons = T.nnet.sigmoid(T.dot(V, h) + c) recon_cost = T.nnet.binary_crossentropy(x_recons, x).mean()
categorical_crossentropy
返回近似分布和真实分布的交叉熵, 如果编码方案是基于给定的概率分布q而非真实分布
p,那么两个概率分布之间的交叉熵衡量的就是从一系列的可能性中区分一个时间所需要的平均编码长度:
H(p,q)=−∑xp(x)log(q(x))
y = T.nnet.softmax(T.dot(W, x) + b) cost = T.nnet.categorical_crossentropy(y, o) # o is either the above-mentioned 1-of-N vector or 2D tensor
h_softmax
实现的是两层层级softmax, 如果输出的数目很重要的时候, 此函数就是softmax的另一个可选项theano.tensor.nnet.h_softmax(x, batch_size, n_outputs, n_classes, n_outputs_per_class, W1, b1, W2, b2, target=None)
参数说明:
x:批大小*特征数, 也就是双层层级softmax的小批输入
batch_size: 输入
x的小批大小
n_outputs: 输出的个数
n_classes:双层层级softmax的类别数, 对应第一个softmax的输出数目
n_outputs_per_class:每一类的输出个数
W1: 输入
x的特征数*类别数, 第一个softmax的权重矩阵, 将输入
x映射到类别概率
b1: 维度就是类别数, 第一个softmax的偏置
W2:(类别数*输入
x的特征总数*
n_outputs_per_class, 第二个softmax的权重矩阵
b2: 维度是
n_classes*
n_outputs_per_class,第二个softmax的偏置
target:维度是(batch_size,)或者(batch_size,1),对于每一个输入计算对应的目标输出, 如果为
None, 那么就计算每个输入对应的所有输出
返回值: 取决于
target, 它有两种不同大小的输出. 如果
target没有指定(
None)的时候, 那么所有的输出就被计算出来, 而且返回值大小为(
batch_size,
n_outputs), 反之, 当
target指定以后, 仅仅有对应的输出被返回, 大小是(
batch_size,1)
注意:
n_output_per_class与
n_classes的乘积必须大于或者等于
n_outputs,如果严格大于, 那么相关输出将会被忽略.
n_outputs_per_class和
n_classes必须与
W1,
b1,
W2和
b2的对应维度相同。计算效率最高的时候是当n_outputs_per_class和n_classes等于n_outputs的平方根时
【PS】感觉意思就是说返回的是(输入样本*预测出的标签)或者是(输入样本*所有可能标签的预测值), 到底是不是, 以后遇到再说.
卷积网络中处理图像的操作
images2neibs
#常用于池化操作 theano.tensor.nnet.neighbours.images2neibs(ten4, neib_shape, neib_step=None, mode='valid')
就不翻译文档了, 函数功能大概就是讲输入图像
ten4按照大小为
neib_shape的块滑动从图像中取块, 并将每一块拉成一个向量存着
参数:
ten4: 输入图像, 四维的,
(dim1,dim2,row,col)前两个维度可以是通道和批
neib_shape: 包含两个值, 滑动窗口的高宽
neib_step:滑动的时候跳过的间隔, 类似于卷积的步长, 但是跳过的应该是块, 也就是说如果值为
1, 那么每次取得的块是相邻但是不想交的, 比如(4,4)就是取行第1-4,5-8,9-12….的块, 而卷积是取1-4,2-5,3-6的块,这也就是为什么我们搜这个函数, 在谷歌上展示的都是实现池化操作的原因
mode:
valid需要输入是池化因子的倍数,
ignore_borders: 如果不是倍数, 就忽视边界
看个例子:
# Defining variables images = T.tensor4('images',dtype= theano.config.floatX) neibs = T.nnet.neighbours.images2neibs(images, neib_shape=(5, 5)) # Constructing theano function window_function = theano.function([images], neibs) # Input tensor (one image 10x10) im_val = np.arange(100.,dtype=theano.config.floatX).reshape((1, 1, 10, 10)) # Function application neibs_val = window_function(im_val) print im_val print neibs_val
可以发现原始图像为
[[[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] [ 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.] [ 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.] [ 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.] [ 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.] [ 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.] [ 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.] [ 70. 71. 72. 73. 74. 75. 76. 77. 78. 79.] [ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89.] [ 90. 91. 92. 93. 94. 95. 96. 97. 98. 99.]]]]
而用[5*5]的块滑动取值以后变成了
[[ 0. 1. 2. 3. 4. 10. 11. 12. 13. 14. 20. 21. 22. 23. 24. 30. 31. 32. 33. 34. 40. 41. 42. 43. 44.] [ 5. 6. 7. 8. 9. 15. 16. 17. 18. 19. 25. 26. 27. 28. 29. 35. 36. 37. 38. 39. 45. 46. 47. 48. 49.] [ 50. 51. 52. 53. 54. 60. 61. 62. 63. 64. 70. 71. 72. 73. 74. 80. 81. 82. 83. 84. 90. 91. 92. 93. 94.] [ 55. 56. 57. 58. 59. 65. 66. 67. 68. 69. 75. 76. 77. 78. 79. 85. 86. 87. 88. 89. 95. 96. 97. 98. 99.]]
neibs2images
就是images2neibs的逆操作
theano.tensor.nnet.neighbours.neibs2images(neibs, neib_shape, original_shape, mode='valid')
可以把上面的
neibs_val还原成原始图片矩阵
im_new = T.nnet.neighbours.neibs2images(neibs, (5, 5), im_val.shape) # Theano function definition inv_window = theano.function([neibs], im_new) # Function application im_new_val = inv_window(neibs_val) print im_new_val
输出
[[[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] [ 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.] [ 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.] [ 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.] [ 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.] [ 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.] [ 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.] [ 70. 71. 72. 73. 74. 75. 76. 77. 78. 79.] [ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89.] [ 90. 91. 92. 93. 94. 95. 96. 97. 98. 99.]]]]
Batch Normalization
batch_normalization_train
theano.tensor.nnet.bn.batch_normalization_train(inputs, gamma, beta, axes='per-activation', epsilon=0.0001, running_average_factor=0.1, running_mean=None, running_var=None)
简介: 对于给定输入计算批归一化, 使用输入的均值和方差,下图摘自论文笔记-Batch Normalization
参数
axes: 输入的需要沿着哪个轴被归一化,取值为‘per-activation’, ‘spatial’ or a tuple of ints, 好像这个取值还会影响最终结果的好坏, 详细请戳这里
gamma: 缩放因子
beta: 偏置
epsilon:批归一化公式中的ϵ,最小1e−5
running_average_factor: 更新运行时均值和方差使用的更新因子
running_mean:
running_mean * (1 - r_a_factor) + batch mean * r_a_factor
running_var:
running_var * (1 - r_a_factor) + (m / (m - 1)) * batch var * r_a_factor
返回值:
out: 批归一化后的输入
mean: 沿着归一化轴的输入的均值
invstd: 沿着归一化轴的输入的逆标准差
new_running_mean: 运行时的均值
new_running_var: 运行时方差
这个函数的操作等价于:
# for per-activation normalization axes = (0,) # for spatial normalization axes = (0,) + tuple(range(2, inputs.ndim)) mean = inputs.mean(axes, keepdims=True) var = inputs.var(axes, keepdims=True) invstd = T.inv(T.sqrt(var + epsilon)) out = (inputs - mean) * gamma * invstd + beta m = T.cast(T.prod(inputs.shape) / T.prod(mean.shape), 'float32') running_mean = running_mean * (1 - running_average_factor) + \ mean * running_average_factor running_var = running_var * (1 - running_average_factor) + \ (m / (m - 1)) * var * running_average_factor
batch_normalization_test
theano.tensor.nnet.bn.batch_normalization_test(inputs, gamma, beta, mean, var, axes='per-activation', epsilon=0.0001)
对给定的输出使用给定的均值和方差进行批归一化, 参数就不说了, 输出是被归一化的输入. 这个操作的等价代码如下:
# for per-activation normalization axes = (0,) # for spatial normalization axes = (0,) + tuple(range(2, inputs.ndim)) gamma, beta, mean, var = (T.addbroadcast(t, *axes) for t in (gamma, beta, mean, var)) out = (inputs - mean) * gamma / T.sqrt(var + epsilon) + beta
batch_normalization
theano.tensor.nnet.bn.batch_normalization(inputs, gamma, beta, mean, std, mode='low_mem')
与上面的区别就是这个函数虽然使用了GPU, 但是没有使用cuDNN优化,还有其它的暂时也不清楚, 以后遇到再看看具体用法
其它
SparseBlockGemv
好像就是一个图像中取出某一块, 然后将它乘以一个矩阵之类并返回一条向量的操作, 调用方法不太懂, 是个类方法class theano.tensor.nnet.blocksparse.SparseBlockGemv(inplace=False)
操作类似于这样
for b in range(batch_size): for j in range(o.shape[1]): for i in range(h.shape[1]): o[b, j, :] += numpy.dot(h[b, i], W[iIdx[b, i], oIdx[b, j]])
这个图解释的很清楚
也就是按照
outputIdx和
inputIdx对
W进行索引, 然后与
h对应位置相乘,而且也举了个例子当
outputIdx=1也就是
j=3时候的计算方法
make_node(o, W, h, inputIdx, outputIdx)
简介: 计算指定一条向量和矩阵的点乘.
参数:
o: 输出向量, 大小为(batch*, oWin, *oSize)
W: 权重矩阵, 大小为(iBlocks*, oBlocks, iSize, *oSize)
h: 低层的输入, 大小为(batch*, iWin, *iSize)
inputIdx: 输入块的索引, 大小为(batch*, *iWin)
outputIdx: 输出块的索引, 大小为 (batch*, *oWin)
返回值:
dot(W[i, j], h[i]) + o[j], 大小为(batch, oWin, oSize)
注意:
batch:是批大小
iSize: 是每个输入块的大小
iWin: 是作为输入的块的数目, 这些块被
inputIdx指定
oBlock: 是可能的输出块的数目
oSize: 是输出块的大小
oWin是输出块的数目, 可以被计算出来,每块是通过
outputIdx计算的
SparseBlockOuter
class theano.tensor.nnet.blocksparse.SparseBlockOuter(inplace=False)
计算两组向量的外积, 使用结果更新整个矩阵, 操作类似于
for b in range(batch_size): o[xIdx[b, i], yIdx[b, j]] += (alpha * outer(x[b, i], y[b, j]))
make_node(o, x, y, xIdx, yIdx, alpha=None)
输入参数:
o: (xBlocks*, yBlocks, xSize, *ySize)
x: (batch*, xWin, *xSize)
y: (batch*, yWin, *ySize)
xIdx:
x块的索引(batch*, *iWin)
yIdx:
y块的索引(batch*, *oWin)
返回值:
outer(x[i], y[j]) + o[i, j], 大小是(xBlocks, yBlocks, xSize, ySize)
注意
batch是批大小
xBlocks是x中的块的总数
xSize是这些x块中的每一个的大小。
xWin是将用作x的块的数量,将使用哪些块在xIdx中指定。
yBlocks是数字或可能的y块。
ySize是这些y块中的每一个的大小。
yWin是实际计算的y块的数量,将在yIdx中指定要计算的块。
sparse_block_dot
theano.tensor.nnet.blocksparse.sparse_block_dot(W, h, inputIdx, b, outputIdx)
简介: 计算指定的向量和矩阵的点积(加上偏差)
参数:
W: 权重矩阵, 大小为(iBlocks*, oBlocks, iSize, *oSize)
h: 低层输入, 大小为(batch*, iWin, *iSize)
inputIdx: 输入块的索引, 大小为 (batch*, *iWin)
b: 偏置向量, 大小为 (oBlocks*, *oSize)
outputIdx: 输出索引, 大小为 (batch*, *oWin)
返回值:
dot(W[i, j], h[i]) + b[j], 大小是(batch, oWin, oSize)
注意
batch是批次大小。
iBlocks是输入(来自较低层)中的块的总数。
iSize是每个输入块的大小。
iWin是将用作输入的块的数量,哪些块将在
inputIdx中指定,
oBlocks是数字或可能的输出块。
oSize是每个输出块的大小。
oWin1是实际计算的输出块数,将在
outputIdx中指定要计算哪些块。
后记
这一次学习比较枯燥, 看了很多函数都不知道怎么用, 但是知道了里面有很多卷积操作, 提供了一堆激活函数和损失函数及其变种, 还可以实现池化操作, 具有batch normalize的实现, 还能指定对那一块进行乘法操作, 然后更新整个矩阵. 厉害了我的theano!!
相关文章推荐
- AndrewNg神经网络和深度学习笔记-Week3-6激活函数
- 神经网络与深度学习 笔记4 交叉熵代价函数 softmax函数
- Linux 路由 学习笔记 之十一 输入、输出路由查找相关的接口函数
- 神经网络与深度学习笔记——第4章 神经网络可以计算任何函数的可视化证明
- 【theano-windows】学习笔记六——theano中的循环函数scan
- 【theano-windows】学习笔记五——theano中张量部分函数
- 机器学习笔记:形象的解释神经网络激活函数的作用是什么?
- 【theano-windows】学习笔记十六——深度信念网络DBN
- MATLAB神经网络学习笔记之:利用learnp函数对感知器网络实现‘或’门
- 七月算法深度学习 第三期 学习笔记-第八节 循环神经网络与相关应用
- 神经网络与深度学习笔记(四)为什么用交叉熵代替二次代价函数
- 深度学习笔记之神经网络、激活函数、目标函数和深度的初步认识
- [DeeplearningAI笔记]神经网络与深度学习3.2_3.11(激活函数)浅层神经网络
- 神经网络学习笔记 - 激活函数的作用、定义和微分证明
- 【theano-windows】学习笔记二——theano中的函数和共享参数
- 笔记: 斯坦福大学机器学习第九课“神经网络的学习(Neural Networks: Learning)”
- 斯坦福机器学习公开课笔记(五)--神经网络的表示
- 神经网络学习笔记_1(BP网络分类双螺旋线) 作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet
- UFLDL 教程学习笔记(一)神经网络
- 神经网络学习笔记 - lecture3:The backpropagation learning proccedure