很多人都讲在神经网络处理前要进行归一化,有很多好处,比如让各个参数值的影响力初始的时候都一样等等。
今天我不讲这个,我来讲一个我实际的例子,说说归一化的问题。
我最近在学习keras,为了搞明白这个的网络结构和运算原理,我决定一层一层,一点一点的通过keras的函数搭建一个网络。
网络很简单,就是一个输入,一个输出,线性网络,没有阈值没有激活函数。简单的说就是想验证一下计算过程和训练过程。
问题来了,当我设置一个较小的输入和输出的时候,比如[1,2,3,4]和[2,4,6,8]的时候,很容易就训练出来。
但是我增加了样本数量设置成 np.arange(1, 100, 1, dtype=‘float32‘)的时候,网络就开始不能收敛了。
我百思不得其解啊。
和一个同事讨论,他给的结论是过拟合,但是我觉得不是。
于是乎,我反复实现,甚至用笔算了权值偏导等数据。终于发现问题所在。
首先,keras的SGD优化算子按MSE进行优化的时候是使用2*(z-y)*x计算的。
当我输入的样本数据过大的时候,这个权值就不能到最优解点上,会反复横跳,甚至可能第一跳变大后,以后越来越大。
要解决这个问题,要么加一个很小的学习率,要么把输入样本进行归一化。
另外,我查到一个帖子,说keras返回的loss和mse不一样。这个原因是因为loss是进行前向计算时的loss,而那个帖子是在train后才predict,当然mse对不上。看我的代码82和87行算出的数据是一样的,但和85行不一样。
1 """ 2 一个线性拟合的例子,根据方程y = 2*x1 + 4* x2进行拟合。 3 只设置了两组数据,[1,2]=>10和[3,4]=>22。 4 设置了一个线性网络 5 6 如果只设置一层的话,可以用很少的epoch就完成训练,比如5次。 7 如果设置了两层的话,epoch较少的时候就会出现较大误差,训练次数达到1000次的时候才能得到正确的结果 8 9 """ 10 import matplotlib.pyplot as plt 11 import numpy as np 12 from tensorflow.keras.models import Sequential 13 import tensorflow as tf 14 from tensorflow.keras.layers import Dense, Activation 15 16 17 def load_complex_data(): 18 ################################## 19 # 这下面的样本数量,11或者比较小的时候可以训练出来,但是改成101这样的数据时,loss就会无限增加。 20 # 21 ################################## 22 train_input = np.arange(16, 18, 1, dtype=‘float32‘) 23 24 train_input = np.reshape(train_input, (train_input.size // 1, 1)) 25 train_output = np.dot(train_input, np.array([2])) 26 train_output = np.reshape(train_output, (train_input.size // 1, 1)) 27 28 test_input = train_input 29 test_output = train_output 30 return train_input, train_output, test_input, test_output 31 32 33 def load_simple_data(): 34 # 手动书写少量的x和y 35 # 输入x为两个样本[1,2]和[3,4] 36 train_input = np.array([21]) 37 # 设置两个样本的输出 38 train_output = np.array([42]) 39 # 设置一个测试样本 40 test_input = np.array([[3, 4]]) 41 test_output = np.array([22]) 42 return train_input, train_output, test_input, test_output 43 44 45 x_train, y_train, x_test, y_test = load_simple_data() 46 47 print(x_train, y_train) 48 49 model = Sequential() 50 51 dense1 = Dense(1, input_shape=(1,), use_bias=False) 52 # dense2 = Dense(1, input_shape=(1, ), use_bias=False) 53 54 model.add(dense1) 55 sgd = tf.keras.optimizers.SGD(learning_rate=0.00001, momentum=0.0) 56 # model.add(dense2) 57 model.compile(optimizer=sgd, loss=‘mse‘) 58 # print(‘models layers:‘, model.layers) 59 # print(‘models config:‘, model.get_config()) 60 # print(‘models summary:‘, model.summary()) 61 layer1 = model.get_layer(name=‘dense‘) 62 layer1_W_pro = layer1.get_weights() 63 print("layer1_W_pro", layer1_W_pro) 64 65 # 显示第二册的权值 66 # layer2 = model.get_layer(name=‘dense_1‘) 67 # layer2_W_pro = layer2.get_weights() 68 # print("layer2_W_pro", layer2_W_pro) 69 70 # 手动设置权重 71 layer1_W_pro_new = [np.array([[2.1]], dtype=‘float32‘)] 72 layer1.set_weights(layer1_W_pro_new) 73 # layer2_W_pro_new = [np.array([[1]], dtype=‘float32‘)] 74 # layer2.set_weights(layer2_W_pro_new) 75 76 # 单步训练训练 77 for num in range(1, 200): 78 y_predict = model.predict(x_train) 79 error = (y_train - y_predict) 80 error = error * error 81 mse = np.sum(error) / y_train.shape[0] 82 print("mse before", mse) 83 print("before train predict", y_predict) 84 layer1_W_pro = layer1.get_weights() 85 print("layer1_W_pro before train", layer1_W_pro) 86 loss = model.train_on_batch(x_train, y_train) 87 print("loss", loss) 88 layer1_W_pro = layer1.get_weights() 89 print("layer1_W_pro after train", layer1_W_pro) 90 y_predict = model.predict(x_train) 91 print("after trained predict", y_predict) 92 error = (y_train - y_predict) 93 error = error * error 94 mse = np.sum(error) / y_train.shape[0] 95 print("mse after", mse) 96 97 # model.fit(x_train, y_train, epochs=1, batch_size=10) 98 99 # layer1_W_pro = layer1.get_weights() 100 # print("layer1_W_pro after train", layer1_W_pro) 101 102 # 预测 103 # y_predict = model.predict(x_train) 104 # print("y_predict", y_predict) 105 106 # y_predict_test = model.predict(x_test) 107 # print("y_predict_test", y_predict_test)
原文:https://www.cnblogs.com/lijhray/p/13041997.html