简单的CNN神经网络应用计算
一、具体要求:
1、卷积层使用一个函数进行表示,池化层使用一个函数进行表示,不同参数的卷积层 /池化层使用相同的函数输入不同的参数来实现
2、卷积层采用 3×3 的卷积窗口,卷积操作使用 same 型卷积,池化层使用 2×2 的窗口实现
3、卷积层后输出数据通过激活函数进行处理,激活函数使用 sigmoid 函数进行实现
4、整体输入数据与输出数据使用数组进行存储,输入输出数据均使用 float 型数据表示
5、整体构成及参数如下所示,图中上层的输出数据为下层的输入数据
(表中参数信息 中变量意思为:f 为处理窗口的大小,p 为输入数据补零个数,s 为窗口滑动步长, d 为参数的深度/组数)
| 参数信息 | 输入数据维度 | 输出数据维度 | |
|---|---|---|---|
| conv1 | f=3; p=1; s=1; d=64 | 224×224×3 | 224×224×64 |
| conv2 | f=3; p=1; s=1; d=64 | 224×224×64 | 224×224×64 |
| pool1 | f=2; s=2 | 224×224×64 | 112×112×64 |
| conv3 | f=3; p=1; s=1; d=128 | 112×112×64 | 112×112×128 |
| conv4 | f=3; p=1; s=1; d=128 | 112×112×128 | 112×112×128 |
| pool2 | f=2; s=2 | 112×112×128 | 56×56×128 |
二、 常用卷积操作类型
神经网络常用的卷积操作类型有:full、same、vaild 三种
- full 型卷积:卷积窗口从与输入图像开始有相交部分即开始进行卷积

- same 型卷积:从卷积窗口的中心点(K)与输入图像的边角相交开始进行卷积

- vaild 型卷积:从卷积窗口与输入图像完全相交开始进行卷积

三、 常用的激活函数类型
- sigmoid 函数 此函数将取值为( ﹣∞, ∞ ) 的数映射到(0,1)上,其公式及图形如下所示:

- tanh 函数 此函数将取值为( ﹣∞, ∞)的数映射到( 1,1) − 上,其公式及图形如下所示:

- ReLu 函数 又称修正线性单元,弥补了上述函数的梯度消失问题


四、实现代码
输入数据:
input_data = np.random.uniform(0,1,size=[3,224,224])
卷积层:
def conv(input_data, f, p, s, d):
sd,x,y = input_data.shape
conv = np.random.randint(-1,2,size=[sd,d,f,f])
new_x = int(x + 2*p)
new_y = int(y + 2*p)
#随机生成数值在[-1,1]之间的f*f大小卷积核
output_data_1 = np.pad(input_data,((0,0),(p,p),(p,p)),'constant')#补零
output_data_2 = np.zeros((d,sd,x,y))
output_data = np.zeros((d,x,y)))#数组初始化
for i in range(0,d):
for j in range(0,sd):
for p in range(0,new_x-f+1):
for q in range(0,new_y-f+1):
new_array = output_data_1[j,p:p+f,q:q+f]#取出需要卷积的数据
new_data = new_array * conv[j][i]#与权重进行卷积
output_data_2[i][j][p][q] = new_data.sum()#不同通道的数值和
output_data[i] += output_data_2[i][j]
return(sigmoid(output_data))
激活函数:
def sigmoid(input_data):
sd,x,y = input_data.shape
output_data = np.zeros((sd,x,y))
for j in range(0,sd):
for p in range(0,x):
for q in range(0,y):
output_data[j][p][q] = (1/(1+np.exp(-input_data[j][p][q])))
return(output_data)
池化层:
def conv(input_data, f, p, s, d):#最大池化
sd,x,y = input_data.shape
conv = np.random.randint(-1,2,size=[sd,d,f,f])
new_x = int(x + 2*p)
new_y = int(y + 2*p)
output_data_1 = np.pad(input_data,((0,0),(p,p),(p,p)),'constant')
output_data_2 = np.zeros((d,sd,x,y))
output_data = np.zeros((d,x,y))
for i in range(0,d):
for j in range(0,sd):
for p in range(0,new_x-f+1):
for q in range(0,new_y-f+1):#找出被池化数据中最大值
new_array = output_data_1[j,p:p+f,q:q+f]
new_data = new_array * conv[j][i]
output_data_2[i][j][p][q] = new_data.sum()
output_data[i] += output_data_2[i][j]
return(sigmoid(output_data))
每一层的输出:
outputdata1 = conv(input_data,3,1,1,64)
outputdata2 = conv(outputdata1,3,1,1,64)
outputdata3 = pool(outputdata2,2,2)
outputdata4 = conv(outputdata3,3,1,1,128)
outputdata5 = conv(outputdata4,3,1,1,128)
outputdata6 = pool(outputdata5,2,2)
1万+

被折叠的 条评论
为什么被折叠?



