拓冰建站拓冰建站
首页 / 资讯中心 / 正文

python简单神经网络:识别手写数字

最基础的神经网络import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import os #激活函数为神经网络引入非线性 def sigmoid(x): return 1/(1np.exp(x)) #避免数值溢出 def softmax(x): c np.max(x) exp_x np.exp(x-c) return exp_x/np.sum(exp_x) #交叉熵 def cross_entropy_error(y,t): #统一格式 if y.ndim 1: y y.reshape(1,-1) t t.reshape(1, -1) delta 1e-7#防止log0 batch_size y.shape[0] return -np.sum(t * np.log(y delta)) / batch_size #求偏微分 def numercial_gradient(f,x): h 1e-4 grad np.zeros_like(x) it np.nditer(x, flags[multi_index], op_flags[readwrite])#高效迭代以multi_index记录当前点的坐标 while not it.finished: idx it.multi_index tmp x[idx] x[idx] h fx1 f() x[idx] - 2*h fx2 f() grad[idx] (fx1- fx2)/(2*h) x[idx] tmp # 恢复 it.iternext() return grad #一层隐藏层的类 save_dir saves class two_layer_net: #权重的初始化 def __init__(self,input_size, hidden_size, output_size, weight_init_std0.01): self.params {} if os.path.exists(saves/params_W1.npy): self.params[W1] np.load(saves/params_W1.npy) self.params[W2] np.load(saves/params_W2.npy) self.params[b1] np.load(saves/params_b1.npy) self.params[b2] np.load(saves/params_b2.npy) else: if os.path.exists(/saves/): os.makedirs(save_dir) self.params[W1] weight_init_std * np.random.randn(input_size,hidden_size)#正态分布的初始值 self.params[W2] weight_init_std * np.random.randn(hidden_size,output_size) self.params[b1] np.zeros(hidden_size,dtypenp.float64) self.params[b2] np.zeros(output_size,dtypenp.float64) def predict(self,x): W1 self.params[W1] W2 self.params[W2] b1 self.params[b1] b2 self.params[b2] z1 np.dot(x,W1)b1 z1 sigmoid(z1) z2 np.dot(z1,W2)b2 z2 softmax(z2) return z2 def loss(self,x,t): y self.predict(x) return cross_entropy_error(y,t) def accuracy(self,x,t): y self.predict(x) y np.argmax(y,axis1) if t.ndim ! 1 : t np.argmax(t, axis1) return np.sum(y t)/float(x.shape[0]) def numerical_gradient(self,x,t): lost_w lambda:self.loss(x,t) grads {} grads[W1] numercial_gradient(lost_w,self.params[W1]) grads[W2] numercial_gradient(lost_w,self.params[W2]) grads[b1] numercial_gradient(lost_w,self.params[b1]) grads[b2] numercial_gradient(lost_w,self.params[b2]) return grads #下载MNIST数据 (x_train, t_train), (x_test, t_test) tf.keras.datasets.mnist.load_data() #化为0或1 x_train np.where(x_train 127, 1.0, 0.0).astype(np.float32) x_test np.where(x_test 127, 1.0, 0.0).astype(np.float32) #将二位矩阵展平为一维数组 x_train x_train.reshape(-1, 784) x_test x_test.reshape(-1, 784) #转换为[0,0,1,0,0,0,0,0,0,0]的形式 t_train_onehot np.eye(10)[t_train] t_test_onehot np.eye(10)[t_test] ############################################################ #学习的超参数# train_size 400 batch_size 100 epochs 2 input_size 784 hidden_size 100 output_size 10 learning_rate 0.5 ############################################################ #调整训练的数据大小 x_train x_train[:train_size] x_test x_test[:train_size] t_train_onehot t_train_onehot[:train_size] t_test_onehot t_test_onehot[:train_size] n train_size//batch_size net two_layer_net(input_size, hidden_size, output_size) #为画图记录数据 train_loss_list [] train_acc_list [] test_acc_list [] #开始训练 for epoch in range(epochs): #数据打乱重排防止依赖 idx np.random.permutation(len(x_train)) x_train_shuffled x_train[idx] t_train_shuffled t_train_onehot[idx] for i in range(n): #随机选择 batch_mask np.random.choice(len(x_train), batch_size) x_batch x_train[batch_mask] t_batch t_train_onehot[batch_mask] #计算偏微分 grads net.numerical_gradient(x_batch,t_batch) for key in (W1, b1, W2, b2): net.params[key] - learning_rate * grads[key] #计算损失 loss net.loss(x_batch, t_batch) train_loss_list.append(loss) print(epoch,epoch1,:,(i1)*batch_size,/,train_size) #保存 np.save(os.path.join(save_dir, params_W1.npy), net.params[W1]) np.save(os.path.join(save_dir, params_W2.npy), net.params[W2]) np.save(os.path.join(save_dir, params_b1.npy), net.params[b1]) np.save(os.path.join(save_dir, params_b2.npy), net.params[b2]) train_acc net.accuracy(x_train, t_train_onehot) test_acc net.accuracy(x_test, t_test_onehot) train_acc_list.append(train_acc) test_acc_list.append(test_acc) print(fEpoch {epoch1}/{epochs}, Train Acc: {train_acc:.4f}, Test Acc: {test_acc:.4f}) #绘图 plt.figure(figsize(12, 4)) plt.subplot(1,2,1) plt.plot(train_loss_list) plt.title(Training Loss) plt.xlabel(Iterations) plt.ylabel(Loss) plt.subplot(1,2,2) plt.plot(train_acc_list, labelTrain) plt.plot(test_acc_list, labelTest) plt.legend() plt.title(Accuracy per Epoch) plt.xlabel(Epochs) plt.ylabel(Accuracy) plt.show()误差反向传播import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import os def sigmoid(x): return 1 / (1 np.exp(-x)) def softmax(x): if x.ndim 2: c np.max(x, axis1, keepdimsTrue) exp_x np.exp(x - c) return exp_x / np.sum(exp_x, axis1, keepdimsTrue) else: c np.max(x) exp_x np.exp(x - c) return exp_x / np.sum(exp_x) def cross_entropy_error(y, t): if y.ndim 1: y y.reshape(1, -1) t t.reshape(1, -1) delta 1e-7 batch_size y.shape[0] return -np.sum(t * np.log(y delta)) / batch_size save_dir saves if not os.path.exists(save_dir): os.makedirs(save_dir) class two_layer_net: def __init__(self, input_size, hidden_size, output_size, weight_init_std0.01, load_pathNone): self.params {} if load_path and os.path.exists(load_path): # 从指定路径加载 data np.load(load_path) self.params[W1] data[W1] self.params[b1] data[b1] self.params[W2] data[W2] self.params[b2] data[b2] print(f从 {load_path} 加载权重成功) elif os.path.exists(saves/model.npz): # 从默认路径加载 data np.load(saves/model.npz) self.params[W1] data[W1] self.params[b1] data[b1] self.params[W2] data[W2] self.params[b2] data[b2] print(从 saves/model.npz 加载权重成功) else: # 随机初始化 self.params[W1] weight_init_std * np.random.randn(input_size, hidden_size) self.params[b1] np.zeros(hidden_size) self.params[W2] weight_init_std * np.random.randn(hidden_size, output_size) self.params[b2] np.zeros(output_size) print(使用随机初始化) def predict(self, x): W1, b1 self.params[W1], self.params[b1] W2, b2 self.params[W2], self.params[b2] z1 np.dot(x, W1) b1 a1 sigmoid(z1) z2 np.dot(a1, W2) b2 y softmax(z2) return y def loss(self, x, t): y self.predict(x) return cross_entropy_error(y, t) def accuracy(self, x, t): y self.predict(x) y np.argmax(y, axis1) if t.ndim ! 1: t np.argmax(t, axis1) return np.sum(y t) / float(x.shape[0]) def gradient(self, x, t): W1, b1 self.params[W1], self.params[b1] W2, b2 self.params[W2], self.params[b2] # 前向 z1 np.dot(x, W1) b1 a1 sigmoid(z1) z2 np.dot(a1, W2) b2 y softmax(z2) # 反向 grads {} delta2 (y - t) / x.shape[0] grads[W2] np.dot(a1.T, delta2) grads[b2] np.sum(delta2, axis0) delta1 np.dot(delta2, W2.T) * (a1 * (1 - a1)) grads[W1] np.dot(x.T, delta1) grads[b1] np.sum(delta1, axis0) return grads # 加载数据 (x_train, t_train), (x_test, t_test) tf.keras.datasets.mnist.load_data() x_train np.where(x_train 127, 1.0, 0.0).astype(np.float32) x_test np.where(x_test 127, 1.0, 0.0).astype(np.float32) x_train x_train.reshape(-1, 784) x_test x_test.reshape(-1, 784) t_train_onehot np.eye(10)[t_train] t_test_onehot np.eye(10)[t_test] # 超参数 train_size 60000 batch_size 100 epochs 10 input_size 784 hidden_size 100 output_size 10 learning_rate 0.1 def train(): # 使用局部变量 x_train_sub x_train[:train_size] t_train_sub t_train_onehot[:train_size] x_test_sub x_test t_test_sub t_test_onehot n len(x_train_sub) // batch_size net two_layer_net(input_size, hidden_size, output_size) train_loss_list [] train_acc_list [] test_acc_list [] for epoch in range(epochs): # 打乱 idx np.random.permutation(len(x_train_sub)) x_train_shuffled x_train_sub[idx] t_train_shuffled t_train_sub[idx] for i in range(n): batch_mask np.random.choice(len(x_train_sub), batch_size) x_batch x_train_shuffled[batch_mask] t_batch t_train_shuffled[batch_mask] grads net.gradient(x_batch, t_batch) for key in (W1, b1, W2, b2): net.params[key] - learning_rate * grads[key] loss net.loss(x_batch, t_batch) train_loss_list.append(loss) #print(fepoch {epoch1}, step {i1}/{n}, loss: {loss:.4f}) # 保存 np.savez(saves/model.npz, W1net.params[W1], b1net.params[b1], W2net.params[W2], b2net.params[b2]) train_acc net.accuracy(x_train_sub, t_train_sub) test_acc net.accuracy(x_test_sub, t_test_sub) train_acc_list.append(train_acc) test_acc_list.append(test_acc) print(fEpoch {epoch1}/{epochs}, Train Acc: {train_acc:.4f}, Test Acc: {test_acc:.4f}) # 绘图 plt.figure(figsize(12, 4)) plt.subplot(1,2,1) plt.plot(train_loss_list) plt.title(Training Loss) plt.subplot(1,2,2) plt.plot(train_acc_list, labelTrain) plt.plot(test_acc_list, labelTest) plt.legend() plt.title(Accuracy) plt.show() train()
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门