首页 > 其他 > 详细

学习keras心得--一个奇怪的问题(由未归一化引起的)

时间:2020-06-04 13:23:45      阅读:139      评论:0      收藏:0      [点我收藏+]

很多人都讲在神经网络处理前要进行归一化,有很多好处,比如让各个参数值的影响力初始的时候都一样等等。

今天我不讲这个,我来讲一个我实际的例子,说说归一化的问题。

我最近在学习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)

 

学习keras心得--一个奇怪的问题(由未归一化引起的)

原文:https://www.cnblogs.com/lijhray/p/13041997.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!