神经网络-全连接层

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=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]]).T

net=Net(2,4,1,0.1)
net.train(X,y)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值