开放实验作业
1.sigmoid函数与tanh函数的梯度消失:
写出函数表达式:
sigmoid函数:
tanh函数:
对两函数进行求导可以得到:
以sigmoid函数导数的图像为例:
令,当z的取值较大时,会发现两个函数的导数都会趋于0,这使得神经网络反馈进行梯度下降时十分缓慢,不利于权重的更新。举个一元多层神经网络的例子:
根据链式法则得到求导公式: 偏差与方差关系
当模型开始训练时,注意到的细节较少,训练出的每个预测值都会与真实值有一定差距,这时会出现偏差较大的情况。当训练时间过长,出现过拟合的情况时,输入一组数据,因模型很复杂,只能代表训练的数据而代表不了所有数据,所以得到的结果可能与实际值差别很大,即方差较大。
6.解决模型过拟合与欠拟合:
6.1.解决模型的过拟合:
1.增加一个正则化因子,在模型预测时,目标损失函数可改写为:
其中被称之为惩罚项,为大于0的常数,有不同的表示方法,取其中一种:
在此情况下,当计算下降梯度时,表达式变为:
这样的话,权重更新时原有的权重因子影响变小,权重本身会减小到比以前更小的值,避免了梯度“一家独大”的现象。
2.适当减少分类时的物品属性或回归时的多项式最高项次数。
3.在深度神经网络学习时,可以适当让部分神经元“坏死”,每次坏死的神经元随机。我认为这种方法在神经元较多时使用,减小了模型复杂度。
6.2 .解决模型欠拟合:
1.对于离散自变量,可以增添更多参数。例如在预测物品种类时,增加物品更多的属性。
2.对于连续性自变量,可以考虑增加多项式的次数。
3.取消正则化因子。
6.3.其他训练方法:
交叉验证:先将数据集划分为个大小相似的互斥子集,,每次选取个子集的并集作为训练集,剩下的为测试集,可以进行次测试,返回的是次预测结果的平均值。
7.卷积神经网络相较于MLP的优点:
在进行图像处理时,假设一幅RGB图像的长与宽皆为,那么图像矩阵中有组数据,在进行神经网络训练时输入向量维数过大。使用CNN(卷积神经网络)可以提取图像中的有效信息,将卷积后的矩阵作为输入向量,训练复杂度更小。同时,可以通过反馈机制一步步优化filter矩阵。
编程题代码:
1.图片处理:
from PIL import Image
import numpy as np
def photo_array():
I = Image.open('D:/engineer/opencv/number.jpg')
I.show()
I_array = np.array(I)
width=np.size(I_array,0)
height=np.size(I_array,1)
I_array=I_array.reshape(height,width,3)
print(I_array)
return I_array
#该函数输出一个 行数*列数*3 的矩阵
2.函数编辑:
import math
import numpy as np
def sigmoid(weight,x,b):
z=float(weight.dot(x)+b)
return 1/(1+math.exp(z))
def tanh(weight,x,b):
z=float(weight.dot(x)+b)
return (math.exp(2*z)-1)/(math.exp(2*z)+1)
def diff_sigmoid(weight,x,b):#导数1
diff1=weight
z=float(weight.dot(x)+b)
diff2=-math.exp(z)/(1+math.exp(z))**2
return diff2*diff1
def diff_tanh(weight,x,b):#导数2
diff1=weight
z=float(weight.dot(x)+b)
diff2=4/(math.exp(z)+math.exp(-z))**2
return diff2*diff1
3.使用普通的卷积运算函数
#输入:原始矩阵,filter矩阵,卷积中心点,filter矩阵长与宽
import numpy as np
import math as mt
def filter_read(mat1,mat2,r1,c1,r2,c2):
number=0
for i1 in range(r2):
for j1 in range(c2):
number+=np.dot(mat1[r1-int((r2-1)/2)+i1][c1-int((c2-1)/2)+j1],mat2[i1][j1])
return number#计算filter矩阵的每一通道与原矩阵通道的乘积
4.使用polling(寻找最大值)的方式卷积函数:
import numpy as np
import math as mt
def filter_read(mat,r1,c1,r2,c2):
mat1=np.zeros([r2,c2])
for i1 in range(r1):
for i2 in range(c1):
mat1[i1][i2]=mat[r1-(r2-1)/2+i1][c1-(c2-1)/2+i2]
return mat1
5.卷积计算函数
#函数参数为,原矩阵,步长,padding长度,filter矩阵个数,filter矩阵
def cnn(origin_mat,s,p,nf,filter_cnn):
o_row=np.size(origin_mat,0)#行数
o_col=np.size(origin_mat,1)#列数
f_row=np.size(filter_cnn[0],0)#filter行数
f_col=np.size(filter_cnn[0],1)#filter列数
origin1_mat=np.zeros([o_row+2*p,o_col+2*p,3])##三通道矩阵
for h1 in range(o_row):
for h2 in range(o_col):
origin1_mat[h1+p][h2+p]=origin_mat[h1][h2]
o_row=o_row+2*p#padding后的矩阵行
o_col=o_col+2*p#padding后的列
c_row=mt.floor((o_row+2*p-f_row)/s+1)
c_col=mt.floor((o_col+2*p-f_row)/s+1)
change_mat=np.zeros([nf,c_row,c_col])#卷积后矩阵
start_row=int((f_row-1)/2)
start_col=int((f_col-1)/2)#选取卷积中心
for i in range(nf):
for j1 in range(c_row-1):
for j2 in range(c_col-1):
print(origin1_mat[start_row][start_col])
change_mat[i][j1][j2]=filter_read(origin1_mat,filter_cnn[i],start_row,start_col,f_row,f_col)
start_col+=s
start_col=int((f_col-1)/2)
start_row+=s#卷积中心改变,使用步长
start_row=int((f_row-1)/2)
start_col=int((f_col-1)/2)
print(start_row)
return change_mat
#实际运用
test1=np.random.randint(0,255,size=[500,500,3])
#随机生成一个图片矩阵
test_s=5
test_p=2
test_nf=3
filter_cnn=np.random.randint(0,3,size=[test_nf,3,3,3])
print(filter_cnn)
new1=cnn(test1,test_s,test_p,test_nf,filter_cnn)
print(new1)
print('新矩阵的行数:',np.size(new1,0))
print('新矩阵的列数:',np.size(new1,1))
print(
结果:
结果.png
读取图片卷积结果:
结果2.png
网友评论