高级人工智能案例——实践
指导老师:陈爱斌教授
1.数据读取与处理
# 存放数据
dataset = []
# 存放标签
labels = []
#读取数据和标签
with open('Iris归一化.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
dataset.append(row[0:4])
labels.append(row[4:7])
#测试是否读取成功
cc = list(zip(dataset, labels))
# 打乱数据集
random.shuffle(cc)
dataset[:], labels[:] = zip(*cc)
print(len(dataset))
print(len(labels))
print(dataset[len(dataset)-1])
print(labels[len(labels)-1])
# 标签转换
labelset = []
for i in labels:
t = []
for j in i:
j = float(j)
t.append(j)
labelset.append(t)
print(labelset)
2.激活函数的定义
本次实践使用了两种激活函数,其图像分别如下:
另外,了解一下这几个
因此,本实验函数定义如下:
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def relu(x):
return np.where(x<0, 0, x)
3.参数初始化
#x为输入矩阵的列数维度,y为输入右乘的列数维度,即隐藏层节点个数,z为输出层节点个数
def parameter_initialization(x, y, z):
# 隐藏层偏差
value1 = np.random.randn(1, y) * 0.01
# 输出层偏差
value2 = np.random.randn(1, z) * 0.01
# 输入层与隐层的连接权重
weight1 = np.random.randn(x, y) * 0.01
# 隐层与输出层的连接权重
weight2 = np.random.randn(y, z) * 0.01
return weight1, weight2, value1, value2
4.模型训练函数
def trainning(dataset, labelset, weight1, weight2, value1, value2):
# x为学习率
x = 0.01
for i in range(len(dataset)):
# 输入数据
inputset = np.mat(dataset[i]).astype(np.float64)
# 数据标签
outputset = np.mat(labelset[i]).astype(np.float64)
# 隐层输入
input1 = np.dot(inputset, weight1).astype(np.float64)
# 隐层输出
output2 = relu(input1 - value1).astype(np.float64)
# 输出层输入
input2 = np.dot(output2, weight2).astype(np.float64)
# 输出层输出
output3 = sigmoid(input2 - value2).astype(np.float64)
#反向传播更新参数
# 更新公式由矩阵运算表示
#sigmoid在y=output3处的导数
a = np.multiply(output3, 1 - output3)
#a=output3
#outputset - output3标签和结果的损失
#loss*sigmoid在output3处的导数,即是隐藏层2的梯度
g = np.multiply(a, outputset - output3)
#隐藏层2的梯度×隐藏层2,继续向前传播
b = np.dot(g, np.transpose(weight2))
#sigmoid导数
c = np.multiply(output2, 1 - output2)
#c=output2
# 上一层传过来的梯度*sigmoid在output2处的导数,即是隐藏层1的梯度
e = np.multiply(b, c)
#计算梯度
value1_change = -x * e
value2_change = -x * g
weight1_change = x * np.dot(np.transpose(inputset), e)
weight2_change = x * np.dot(np.transpose(output2), g)
# 更新参数
value1 += value1_change
value2 += value2_change
weight1 += weight1_change
weight2 += weight2_change
#print("loss",outputset - output3)
return weight1, weight2, value1, value2
5.模型测试函数
def testing(dataset, labelset, weight1, weight2, value1, value2):
# 记录预测正确的个数
rightcount = 0
for i in range(len(dataset)):
# 计算每一个样例通过该神经网路后的预测值
inputset = np.mat(dataset[i]).astype(np.float64)
output2 = relu(np.dot(inputset, weight1) - value1)
output3 = sigmoid(np.dot(output2, weight2) - value2)
# 求最大值的索引
output3 = output3[0].tolist()
predict = output3.index(max(output3))
label = labelset[i].index(max(labelset[i]))
if(label==predict):
rightcount=rightcount+1
# 输出预测结果
print("预测结果", output3, "标签", labelset[i])
print("预测为", predict, "实际为", label)
#print("预测为%d 实际为%d" % (output3, labelset))
# 返回正确率
return rightcount / len(dataset)
6.训练测试及输出
c = 120
traindata = []
trainlabel = []
testdata = []
testlabel = []
acc = []
for i in range(0, len(labelset)):
if i < c:
traindata.append(dataset[i])
trainlabel.append(labelset[i])
else:
testdata.append(dataset[i])
testlabel.append(labelset[i])
print("训练集:", len(traindata))
print("验证集:", len(testdata))
# 初始化参数
weight1, weight2, value1, value2 = parameter_initialization(len(traindata[0]), len(traindata[0]), 3)
# 训练
for i in range(3000):
print("当前训练epoch", i)
(weight1, weight2, value1, value2) = trainning(traindata, trainlabel, weight1, weight2, value1, value2)
# 验证
rate = testing(testdata, testlabel, weight1, weight2, value1, value2)
acc.append(rate)
print("正确率为%f" % rate)
x = np.arange(0, 3000, 30)
plt.plot(x, np.array(acc)[x])
plt.grid(True)
plt.xlabel("epochs")
plt.ylabel("acc")
plt.show()
7. 实验结果
每次实验跑3000 epochs,每个epoch训练120条数据,测试30条数据
1) 隐藏层输出ReLU+输出层输出SeLU