keras L1正则化不适用于线性回归

wsxa1bj1  于 2024-01-08  发布在  其他
关注(0)|答案(1)|浏览(98)

L1正则化不适用于线性回归,在下面的例子中,我创建了一个数据y = 2x1+ 5x2 + 3*x3 + 5
在数据集中,x4参数是存在的,但是为了计算样本数据中的输出,我们没有使用它,所以当我们应用L1正则化时,我们应该得到w4接近于零,但是它仍然不起作用。

  1. # In[1]:
  2. import pandas as pd
  3. import numpy as np
  4. import tensorflow as tf
  5. from matplotlib import pyplot as plt
  6. # In[2]:
  7. def plot_the_data(training_df, output):
  8. plt.xlabel("feature")
  9. plt.ylabel("label")
  10. plt.ylim([output.min() - 1 , output.max() + 1])
  11. print(training_df.columns)
  12. for column in training_df.columns:
  13. print(training_df[column].shape)
  14. plt.xlabel(column)
  15. plt.scatter(training_df[column], output)
  16. plt.show()
  17. total_data = 10000
  18. output_label = 'output'
  19. normalize_data = True
  20. def createData(total_data):
  21. my_label = np.zeros((total_data,))
  22. my_feature = np.append(np.random.uniform(low=10, high=100, size=(total_data,)).reshape((total_data, 1)), # first col
  23. np.random.uniform(low=300, high=500, size=(total_data,)).reshape((total_data, 1)), axis=1) # sec col
  24. my_feature = np.append(my_feature ,
  25. np.random.uniform(low=600, high=800, size=(total_data,)).reshape((total_data, 1)), axis=1) # third col
  26. my_feature = np.append(my_feature ,
  27. np.random.uniform(low=900, high=1000, size=(total_data,)).reshape((total_data, 1)), axis=1) # fourth col, unused
  28. for i, row in enumerate(my_feature):
  29. my_label[i] = ((2 + np.random.uniform(0.0, 0.1) ) * row[0]) + ((5 + np.random.uniform(0.0, 0.1) )* row[1]) + ((3 + np.random.uniform(0.0, 0.1) )* row[2]) + (50 + np.random.randint(low=1, high=3))
  30. training_df = pd.DataFrame({ 'x1' : my_feature[:,0], 'x2' : my_feature[:,1], 'x3' : my_feature[:,2], 'x4' : my_feature[:,3], 'output': my_label})
  31. return training_df
  32. training_df = createData(total_data)
  33. training_df = training_df.reindex(np.random.permutation(training_df.index))
  34. training_df[output_label] = training_df[output_label] / 1000
  35. print(training_df)
  36. plot_the_data(training_df, training_df[output_label])
  37. # In[3]:
  38. def normalize_the_data(training_df):
  39. normalized_df = pd.DataFrame()
  40. norm_list = {}
  41. for column in training_df.columns:
  42. print(f"Max, Min of {column} pre normalization: {np.max(training_df[column]):0.2f}, {np.min(training_df[column]):0.2f}")
  43. norm_l = tf.keras.layers.Normalization(axis=-1)
  44. norm_l.adapt(training_df[column]) # learns mean, variance
  45. Xn = norm_l(training_df[column])
  46. normalized_df[column] = Xn.numpy()[0]
  47. norm_list[column] = norm_l
  48. print(f"Max, Min of {column} post normalization: {np.max(normalized_df[column]):0.2f}, {np.min(normalized_df[column]):0.2f}")
  49. return normalized_df, norm_list
  50. def normalize_the_test_data(training_df, norm_list):
  51. normalized_df = pd.DataFrame()
  52. for column in training_df.columns:
  53. print(f"Max, Min of {column} pre normalization: {np.max(training_df[column]):0.2f}, {np.min(training_df[column]):0.2f}")
  54. norm_l = norm_list[column]
  55. norm_l.adapt(training_df[column]) # learns mean, variance
  56. Xn = norm_l(training_df[column])
  57. normalized_df[column] = Xn.numpy()[0]
  58. print(f"Max, Min of {column} post normalization: {np.max(normalized_df[column]):0.2f}, {np.min(normalized_df[column]):0.2f}")
  59. return normalized_df
  60. if normalize_data == True:
  61. print("Data Normalization enabled")
  62. norm_l = tf.keras.layers.Normalization(axis=-1)
  63. normalized_df, norm_l = normalize_the_data(training_df)
  64. else:
  65. print("Data Normalization disabled")
  66. normalized_df = training_df
  67. # In[4]:
  68. normalized_df = normalized_df.loc[:, normalized_df.columns != output_label]
  69. # In[5]:
  70. tf.random.set_seed(1)
  71. learning_rate=0.01
  72. my_learning_rate = learning_rate
  73. epochs=20
  74. batch_size=20
  75. validation_split = 0.2
  76. print(normalized_df.head())
  77. model = tf.keras.models.Sequential()
  78. model.add(tf.keras.layers.Dense(units=1, input_shape=(training_df.shape[1] - 1,), kernel_regularizer='l2'))
  79. model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=my_learning_rate),
  80. loss="mean_squared_error",
  81. metrics=[tf.keras.metrics.RootMeanSquaredError(),tf.keras.metrics.Accuracy()])
  82. model.summary()
  83. weights_dict = {}
  84. weight_callback = tf.keras.callbacks.LambdaCallback(on_epoch_end=lambda epoch, logs: weights_dict.update({epoch: { "w" : model.get_weights()[0][0][0], "b" : model.get_weights()[1][0]}}))
  85. history = model.fit(x=normalized_df,
  86. y=training_df[output_label],
  87. # verbose='0',
  88. batch_size=batch_size,
  89. epochs=epochs,
  90. callbacks=weight_callback,
  91. validation_split=validation_split)
  92. # Gather the trained model's weight and bias.
  93. trained_weight = model.get_weights()[0]
  94. trained_bias = model.get_weights()[1]
  95. epochs = history.epoch
  96. hist = pd.DataFrame(history.history)
  97. rmse = hist["root_mean_squared_error"]
  98. testrmse = hist["val_root_mean_squared_error"]
  99. print("Defined build_model and train_model", trained_weight, trained_bias)
  100. # In[6]:
  101. predictions = model.predict(normalized_df)
  102. print(training_df.loc[:, training_df.columns == output_label])
  103. plot_the_data( training_df.loc[:, training_df.columns == output_label], predictions.T)
  104. # In[7]:
  105. def plot_the_data_and_pred(training_df, output, pred):
  106. plt.xlabel("feature")
  107. plt.ylabel("label")
  108. print(training_df.columns)
  109. for column in training_df.columns:
  110. plt.xlabel(column)
  111. plt.scatter(training_df[column], output)
  112. plt.scatter(training_df[column], pred)
  113. plt.show()
  114. plot_the_data_and_pred(training_df, training_df[output_label], predictions)
  115. # In[8]:
  116. def plot_the_loss_curve(epochs, rmse, testrmse):
  117. """Plot the loss curve, which shows loss vs. epoch."""
  118. plt.figure()
  119. plt.xlabel("Epoch")
  120. plt.ylabel("Root Mean Squared Error")
  121. plt.plot(epochs, rmse, label="Training Loss")
  122. plt.plot(epochs, testrmse, label="Validation Loss")
  123. # plt.plot(epochs, rmse, label="Loss")
  124. plt.legend()
  125. #y axis limit for the y axes
  126. plt.ylim([rmse.min()*0.97, rmse.max() + 10])
  127. plt.show()
  128. plot_the_loss_curve(epochs, rmse, testrmse)
  129. # In[9]:
  130. output_label = 'output'
  131. total_test_data = 1000
  132. my_test_label = np.zeros((total_test_data,))
  133. def createTestData(total_data):
  134. my_label = np.zeros((total_data,))
  135. my_feature = np.append(np.random.uniform(low=50, high=60, size=(total_data,)).reshape((total_data, 1)), # first col
  136. np.random.uniform(low=350, high=400, size=(total_data,)).reshape((total_data, 1)), axis=1) # sec col
  137. my_feature = np.append(my_feature ,
  138. np.random.uniform(low=690, high=750, size=(total_data,)).reshape((total_data, 1)), axis=1) # third col
  139. my_feature = np.append(my_feature ,
  140. np.random.uniform(low=950, high=975, size=(total_data,)).reshape((total_data, 1)), axis=1) # fourth col, unused
  141. for i, row in enumerate(my_feature):
  142. my_label[i] = ((2 + np.random.uniform(0.0, 0.1) ) * row[0]) + ((5 + np.random.uniform(0.0, 0.1) )* row[1]) + ((3 + np.random.uniform(0.0, 0.1) )* row[2]) + (50 + np.random.randint(low=1, high=3))
  143. training_df = pd.DataFrame({ 'x1' : my_feature[:,0], 'x2' : my_feature[:,1], 'x3' : my_feature[:,2], 'x4' : my_feature[:,3], 'output': my_label})
  144. return training_df
  145. test_df = createTestData(total_test_data)
  146. test_df[output_label] = test_df[output_label] / 1000
  147. print(test_df)
  148. # plot_the_data(test_df, test_df[output_label])
  149. if normalize_data == True:
  150. print("Data Normalization enabled")
  151. normalised_test_df = normalize_the_test_data(test_df, norm_l)
  152. else:
  153. print("Data Normalization disabled")
  154. normalised_test_df = test_df
  155. normalised_test_df = normalised_test_df.loc[:, normalised_test_df.columns != output_label]
  156. print(normalised_test_df)
  157. test_predictions = model.predict(normalised_test_df)
  158. plot_the_data( test_df.loc[:, test_df.columns != output_label], test_df[output_label])
  159. plot_the_data_and_pred(test_df.loc[:, test_df.columns != output_label], test_df[output_label], test_predictions)
  160. # In[10]:
  161. print("Defined build_model and train_model", trained_weight, trained_bias)
  162. # In[11]:
  163. results = model.evaluate(normalised_test_df, test_df[output_label], batch_size=batch_size)
  164. # In[12]:
  165. tf.random.set_seed(1)
  166. epochs = 20
  167. model = tf.keras.models.Sequential()
  168. model.add(tf.keras.layers.Dense(units=1, input_shape=(training_df.shape[1] - 1,), kernel_regularizer='l1'))
  169. model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=my_learning_rate),
  170. loss="mean_squared_error",
  171. metrics=[tf.keras.metrics.RootMeanSquaredError(),tf.keras.metrics.Accuracy()])
  172. model.summary()
  173. weights_dict = {}
  174. weight_callback = tf.keras.callbacks.LambdaCallback(on_epoch_end=lambda epoch, logs: weights_dict.update({epoch: { "w" : model.get_weights()[0][0][0], "b" : model.get_weights()[1][0]}}))
  175. history = model.fit(x=normalized_df,
  176. y=training_df[output_label],
  177. # verbose='0',
  178. batch_size=batch_size,
  179. epochs=epochs,
  180. callbacks=weight_callback,
  181. validation_split=validation_split)
  182. # Gather the trained model's weight and bias.
  183. trained_weight = model.get_weights()[0]
  184. trained_bias = model.get_weights()[1]
  185. epochs = history.epoch
  186. hist = pd.DataFrame(history.history)
  187. rmse = hist["root_mean_squared_error"]
  188. testrmse = hist["val_root_mean_squared_error"]
  189. print("Defined build_model and train_model", trained_weight, trained_bias)
  190. # In[13]:
  191. results = model.evaluate(normalised_test_df, test_df[output_label], batch_size=batch_size)
  192. # In[ ]:

字符串

mctunoxg

mctunoxg1#

看起来你正在对训练数据进行归一化,但不清楚测试数据是否以同样的方式进行归一化。请确保这样做。
当应用L1正则化时,正则化项应该在模型编译过程中添加到损失函数中。尝试这样做:

  1. model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=my_learning_rate),loss=tf.keras.losses.MeanSquaredError() + tf.keras.regularizers.L1(0.01), metrics=[tf.keras.metrics.RootMeanSquaredError(), tf.keras.metrics.Accuracy()])
  2. model.summary()

字符串
如果你能分享一些玩具数据我就能复制这个了。

相关问题