神经网络-全连接层

python实现的全连接层:

class FC: def __init__(self,in_num,out_num,lr=0.01): self.in_num=in_num self.out_num=out_num self.w=numpy.random.randn(out_num,in_num)*10 self.b=numpy.zeros(out_num) self.lr=lr def _sigmold(self, in_data): return 1/(1+numpy.exp(-in_data)) def forward(self, in_data): self.topVal=self._sigmold(numpy.dot(self.w,in_data)+self.b) self.bottomVal=in_data return self.topVal

全连接层的主要计算类型为矩阵向量乘(GEMV)。
caffe中全连接层直接将前一层的输出展开为一维向量,如果前一层的输出维度为 64 x 50 x 4 x 4,全连接层对应的输入向量的维度为 50*4*4=800。
import numpy import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def draw3D(X,Y,Z,angle): fig=plt.figure(figsize=(15,7)) ax=Axes3D(fig) ax.view_init(angle[0],angle[1]) ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap='rainbow') plt.show() x=numpy.linspace(-10,10,100) y=numpy.linspace(-10,10,100) X,Y=numpy.meshgrid(x,y) X_f=X.flatten() Y_f=Y.flatten() data=https://www.it610.com/article/zip(X_f,Y_f)fc=FC(2,3) fc.w=numpy.array([[0.4, 0.6],[0.3,0.7],[0.2,0.8]]) fc.b=numpy.array([0.5,0.5,0.5])fc2 = FC(3, 1) fc2.w = numpy.array([0.3, 0.2, 0.1]) fc2.b = numpy.array([0.5])z1=numpy.array([fc.forward(d) for d in data]) z2=numpy.array([fc2.forward(d) for d in z1]) z2=z2.reshape(100,100)draw3D(X,Y,z2,(40,-45))

上述代码实现了两个全连接层组成的神经网络。效果图:
神经网络-全连接层
文章图片

全连接层的具体含义:
作者:冯超 链接:https://zhuanlan.zhihu.com/p/21525237 来源:知乎
反向传播 实际中,计算和训练都是一批一批完成的。大多数机器学习训练都有batch的概念,而训练中batch的计算不是一个一个地算,而是一批数据集中算,那么就需要用上矩阵了。
【神经网络-全连接层】参考:
作者:冯超 链接:https://zhuanlan.zhihu.com/p/21572419 来源:知乎
所有相关的训练数据和参数做以下的约定:
  • 所有的训练数据按列存储,也就是说如果把N个数据组成一个矩阵,那个矩阵的行等于数据特征的数目,矩阵的列等于N
  • 线性部分的权值w由一个矩阵构成,它的行数为该层的输入个数,列数为该层的输出个数。如果该层的输入为2,输出为4,那么这个权值w的矩阵就是一个2*4的矩阵。
  • 线性部分的权值b是一个行数等于输出个数,列数为1的矩阵。
import numpy class SquareLoss: def forward(self,y,t): self.loss=y-t return numpy.sum(self.loss*self.loss) / self.loss.shape[1] / 2 def backward(self): return self.loss class FC: def __init__(self,in_num,out_num,lr=0.1): self.in_num=in_num self.out_num=out_num self.w=numpy.random.randn(in_num,out_num) self.b=numpy.zeros((out_num,1)) self.lr=lr def _sigmold(self, in_data): return 1/(1+numpy.exp(-in_data)) def forward(self, in_data): self.topVal=self._sigmold(numpy.dot(self.w.T,in_data)+self.b) self.bottomVal=in_data return self.topVal def backward(self,loss): grad_z=loss * self.topVal * (1-self.topVal) grad_w=numpy.dot(self.bottomVal, grad_z.T) grad_b=numpy.sum(grad_z) self.w -= self.lr*grad_w self.b -= self.lr*grad_b grad_x=numpy.dot(grad_w,grad_z) return grad_x class Net: def __init__(self,input_num=2,hidden_num=4,out_num=1,lr=0.1): self.fc1=FC(input_num,hidden_num,lr) self.fc2=FC(hidden_num,out_num,lr) self.loss=SquareLoss() def train(self, X, y): #X are arraged by col for i in range(10000): #forward step layer1out=self.fc1.forward(X) layer2out=self.fc2.forward(layer1out) loss =self.loss.forward(layer2out,y)#backward step layer2loss=self.loss.backward() layer1loss=self.fc2.backward(layer2loss) saliency=self.fc1.backward(layer1loss)layer1out=self.fc1.forward(X) layer2out=self.fc2.forward(layer1out) loss =self.loss.forward(layer2out,y)print 'X={0}'.format(X) print 't={0}'.format(y) print 'y={0}'.format(layer2out) print 'loss={0}'.format(loss)X=numpy.array([[0,0],[0,1],[1,0],[1,1]]).T y=numpy.array([[0],[0],[0],[1]]).Tnet=Net(2,4,1,0.1) net.train(X,y)

    推荐阅读