应用篇:神经网络用于参数优化案例

1.膜电极参数优化

1.导入数据

1.导入数据

  import pandas as pd
  df = pd.read_csv('MEA.csv',encoding = 'gbk')  #导入数据,使用GBK编码
  print(df)

2.设置输入输出

  import numpy as np
  for i in range(2):  #进行两次神经网络
      x = df.iloc[:, :-2].values  # 设置输入输出,x为第1列到倒数第2列,iloc()通过行列号提取数据
      if i:
          y = df['Pt Consumption per kW@0.65V (mgpt kW-1)'].values
      else:
          y = df['Power Density at 0.6V (mW cm-2)'].values
      x_s = (x-np.mean(x,axis = 0))/np.std(x,axis = 0)  #数据标准化,原数据减平均值后除标准差,axis=0按列计算,np.std()计算标准差
      y_s = (y-np.mean(y))/np.std(y)
      print(x_s,y_s)

3.划分数据集

  from sklearn.model_selection import train_test_split
  x_train,x_test,y_train,y_test= train_test_split(x_s,y_s,  #数据集分割训练和测试,检验占比0.15,随机种子91
                                                  test_size = 0.15,
                                                  random_state = 91)
2.模型构建

1.模型构建

  import tensorflow as tf
  from tensorflow import keras
  model = keras.Sequential(  #构建神经网络
      [
          keras.Input(shape = (19)),
          keras.layers.Dense(300,activation = 'relu',
                             kernel_initializer = 'random_normal',  #权重初始化,随机正态分布
                             bias_initializer = 'random_normal',  #偏移量初始化
                             kernel_regularizer = keras.regularizers.l2(0.001)),  #权重正则化,L2正则化
          keras.layers.Dropout(0.1),  #丢弃法,每次更新丢掉0.1的神经元
          keras.layers.Dense(300, activation = 'relu',
                             kernel_initializer = 'random_normal',
                             bias_initializer = 'random_normal',
                             kernel_regularizer = keras.regularizers.l2(0.001)),
          keras.layers.Dropout(0.1),
          keras.layers.Dense(1)
      ]
  )
  print(model.summary())
  
  adam = keras.optimizers.Adam(learning_rate = 0.001)  #设置学习率
  model.compile(loss = 'mse',optimizer = adam)
  early_stopping = keras.callbacks.EarlyStopping(monitor = 'val_loss',  #设置提前终止
                                               patience = 20)
  history = keras.callbacks.History()  #记录模型
  checkpointer = keras.callbacks.ModelCheckpoint(filepath = 'weights.hdf5',
                                                 save_best_only = True)  #保存模型,保存最好的
  model.fit(x_train,y_train,validation_split = 0.2,epochs = 650,  #validation_split 从测试集中划分多少比例给训练集
            batch_size = 16,verbose = 0,callbacks = [early_stopping])

2.参数初始化
  zeros:全零初始化
  random_normal:随机正态分布
  random_uniform:随机均匀分布
  glorot_normal:Glorot正态分布
  glorot_uniform:Glorot均匀分布(默认)
  he_uniform:何恺明均匀分布

3.预防过拟合

1.增加数据
2.减小网络容量
3.Dropout
  丢弃法:每次更新时,将神经元按比率随机丢弃。
4.权重正则化
5.Mini Batch

全梯度下降随机梯度下降
收敛速度
并行性可并行无法并行

  折中方法:mini Batch
  学习率和样本数量需手动预先指定,不需要通过模型训练得到。
  model.fit()中参数batch_size,用于控制拟合过程的输出,默认32,减小会降低过拟合风险,增大会提高收敛稳定性。
6.提前终止
  EarlyStopping,所监测的指标不再提升时,停止训练。

  keras.callbacks.EarlyStopping(monitor = ‘val_loss’,min_delta = 0,patience = 0,mode = ‘auto’)
  monitor:监测指标,‘acc’,‘val_acc’,‘loss’,‘val_loss’
  min_delta:阈值
  patience:耐心值,容忍多少个epoch内没有提升
  mode:模式,‘auto’,‘min’,‘max’

  回调函数(Callbacks)
  函数合集,可用来查看训练模型的内在状态和统计,并控制回归进程。
  常用的回调函数,EarlyStopping,History,ModelCheckpoint

4.回归过程与结果可视化

1.绘制loss的训练变化图

  #绘制损失值的训练变化图
  import matplotlib.pyplot as plt
  plt.plot(history.history['loss'])  #训练集损失值
  plt.plot(history.history['val_loss'])  #测试集损失值
  plt.title('Model loss')  #标题
  plt.ylabel('Loss')  #x标签,损失值
  plt.xlabel('Epoch')  #y标签,训练次数
  plt.legend(['Train','Val'])  #图例
  plt.show()

2.输出回归模型的评价指标

  from sklearn.metrics import r2_score
  #回归结果展示
  result_train = model.predict(x_train)  #预测值
  result_test = model.predict(x_test)

  y_pred_train = result_train * np.std(y)+np.mean(y)  #逆标准化,预测值
  y_real_train = y_train * np.std(y)+np.mean(y)  #真实值
  y_pred_train = y_pred_train.reshape(-1) #一列变为一行

  y_pred_test = result_test * np.std(y)+np.mean(y)  #逆标准化,预测值
  y_real_test = y_test * np.std(y)+np.mean(y)  #真实值
  y_pred_test = y_pred_test.reshape(-1) #一列变为一行

  def compute_mae_mse_rmse(pred,real):  #自定义计算平均绝对误差mae,均方误差mse,均方根误差rmse,R方r2
      error = []
      for j in range(len(real)):
          error.append(real[j]-pred[j])  #预测值与真实值之差
      error_squared = []
      error_abs = []
      for val in error:
          error_squared.append(val*val)  #误差平方
          error_abs.append(abs(val))  #误差绝对值
      mae = sum(error_abs)/len(error_abs)  #MAE
      mse = sum(error_squared)/len(error_squared)  #MSE
      rmse = np.sqrt(mse)  #均方根误差rmse是均方误差mse的算术平方根
      r2 = r2_score(real,pred)  #评价回归模型,r2->1,模型越好
      return mae,mse,rmse,r2

  error_val_train = compute_mae_mse_rmse(y_pred_train,y_real_train)  #计算误差
  error_val_test = compute_mae_mse_rmse(y_pred_test,y_real_test)

  print('training mae: %.2f,mse: %.2f,rmse: %.2f,r2: %.4f'%(error_val_train[0],error_val_train[1],  #输出预测的误差
                                                              error_val_train[2],error_val_train[3]))
  print('testing mae: %.2f,mse: %.2f,rmse: %.2f,r2: %.4f'%(error_val_test[0],error_val_test[1],
                                                              error_val_test[2],error_val_test[3]))

3.绘制真实—预测对比图

  #绘制回归结果展示,横坐标预测值,纵坐标真实值
  plt.figure(figsize = (8,6))  #设置画图大小
  plt.scatter(y_pred_train,y_real_train,color = 'blue',
              label = 'Artificial Neural Network Traing Set',alpha = 0.25,marker = '^')  #散点图,蓝色三角代表训练集,alpha散点透明度
  plt.scatter(y_pred_test,y_real_test,color = 'red',
              label = 'Artificial Neural Network Test Set',alpha = 0.75)  #散点图,红色圆点代表测试集
  plt.legend()  #图例
  if i:  #设置横纵轴标签
      plt.xlabel('Predicted Pt Consumption per kW@0.65V (mgpt kW-1)')
      plt.ylabel('Real Pt Consumption per kW@0.65V (mgpt kW-1)')
      xx = np.arange(0, 2.5, 0.005)
      yy = np.arange(0, 2.5, 0.005)
      plt.plot(xx, yy)  # 绘制对角线
  else:
      plt.xlabel('Predicted Power Density at 0.6 (mW cm-2)')
      plt.ylabel('Real Power Density at 0.6 (mW cm-2)')
      xx = np.arange(0, 1200, 0.1)
      yy = np.arange(0, 1200, 0.1)
      plt.plot(xx, yy)  # 绘制对角线
  plt.show()
5.模型保存与加载
  model.save('model.h5')  #保存模型
  model_load = keras.model.load_model('model.h5')  #模型加载

1.模型保存
  model.save()
  将模型保存为.h5或者.hdf5文件
  HDF:Hierarchical Data Format(分层数据格式)

2.权重正则化

1.权重可视化
  import tensorflow  as tf
  from tensorflow import keras
  import numpy as np
  import matplotlib.pyplot as plt

  mnist = keras.datasets.mnist  #导入mnist数据集
  (train_images,train_labels),(test_images,test_labels) = mnist.load_data()  #数据集分为训练集和测试集
  train_images,test_images = train_images/255.0,test_images/255.0  #数据范围0-1

  model_0 = keras.Sequential(  #初始模型
      [
          keras.layers.Flatten(input_shape=(28,28)),
          keras.layers.Dense(10,activation = 'softmax',use_bias = False)  #输出层
      ]
  )
  model_0.compile(optimizer = 'adam',
                  loss = 'sparse_categorical_crossentropy',
                  metrics = ['accuracy'])
  w0 = model_0.get_weights()[0]  #获取初始权重
  fig,axs = plt.subplots(2,5,figsize = (15,5))  #绘制子图,画布大小15*5
  for i in range(10):
      w2p = w0[:,i].reshape(28,28)
      axs[int(i/5),i%5].imshow(w2p)  #axs[i,j]位于第i行第j列
  plt.show()

  model_0.fit(train_images,train_labels,epochs = 10)  #训练10次
  w0 = model_0.get_weights()[0]  #获取训练后权重
  fig,axs = plt.subplots(2,5,figsize = (15,5))  #绘制子图,画布大小15*5
  for i in range(10):
      w2p = w0[:,i].reshape(28,28)
      axs[int(i/5),i%5].imshow(w2p)  #axs[i,j]位于第i行第j列
  plt.show()
2.正则化

  对于一个神经网络模型,参数非常多,很容易造成过拟合。
  解决方案:将参数个数考虑到损失函数中
m i n w = ( 1 2 n ∥ X w − y ∥ 2 2 + α ∥ w ∥ 0 ) , ∥ w ∥ 0 w 中非 0 元素的个数 \underset{w}{min}=\left(\frac{1}{2n}\left\|X_{w}-y\right\|_{2}^{2}+\alpha\left\|w\right\|_{0}\right) ,\left\|w\right\|_{0} w中非0元素的个数 wmin=(2n1Xwy22+αw0),w0w中非0元素的个数

3.L1正则化

套索回归(Lasso回归)
m i n w = ( 1 2 n ∥ X w − y ∥ 2 2 + α ∥ w ∥ 1 ) ,其中 ∥ w ∥ 1 = ∑ i ∣ w i ∣ \underset{w}{min}=\left(\frac{1}{2n}\left\|X_{w}-y\right\|_{2}^{2}+\alpha\left\|w\right\|_{1}\right),其中\left\|w\right\|_{1}=\sum_{i}\left|w_{i}\right| wmin=(2n1Xwy22+αw1),其中w1=iwi

  #L1正则化
  model_1 = keras.Sequential(  #初始模型
      [
          keras.layers.Flatten(input_shape=(28,28)),
          keras.layers.Dense(10,kernel_regularizer = keras.regularizers.l1(0.05),  #L1正则化
                           activation = 'softmax',use_bias = False)  #输出层
      ]
  )
  model_1.compile(optimizer = 'adam',
                  loss = 'sparse_categorical_crossentropy',
                  metrics = ['accuracy'])
  w0 = model_1.get_weights()[0]  #获取初始权重
  fig,axs = plt.subplots(2,5,figsize = (15,5))  #绘制子图,画布大小15*5
  for i in range(10):
      w2p = w0[:,i].reshape(28,28)
      axs[int(i/5),i%5].imshow(w2p)  #axs[i,j]位于第i行第j列
  plt.show()

  model_1.fit(train_images,train_labels,epochs = 10)  #训练10次
  w0 = model_1.get_weights()[0]  #获取训练后权重
  fig,axs = plt.subplots(2,5,figsize = (15,5))  #绘制子图,画布大小15*5
  for i in range(10):
      w2p = w0[:,i].reshape(28,28)
      axs[int(i/5),i%5].imshow(w2p)  #axs[i,j]位于第i行第j列
  plt.show()
4.L2正则化

岭回归(Ridge回归)
m i n w = ( 1 2 n ∥ X w − y ∥ 2 2 + α ∥ w ∥ 2 ) ,其中 ∥ w ∥ 2 = ∑ i w i 2 \underset{w}{min}=\left(\frac{1}{2n}\left\|X_{w}-y\right\|_{2}^{2}+\alpha\left\|w\right\|_{2}\right),其中\left\|w\right\|_{2}=\sum_{i}\sqrt{w_{i}^{2}} wmin=(2n1Xwy22+αw2),其中w2=iwi2

  #L2正则化
  model_2 = keras.Sequential(  #初始模型
      [
          keras.layers.Flatten(input_shape=(28,28)),
          keras.layers.Dense(10,kernel_regularizer = keras.regularizers.l2(0.05),  #L1正则化
                           activation = 'softmax',use_bias = False)  #输出层
      ]
  )
  model_2.compile(optimizer = 'adam',
                  loss = 'sparse_categorical_crossentropy',
                  metrics = ['accuracy'])
  w0 = model_2.get_weights()[0]  #获取初始权重
  fig,axs = plt.subplots(2,5,figsize = (15,5))  #绘制子图,画布大小15*5
  for i in range(10):
      w2p = w0[:,i].reshape(28,28)
      axs[int(i/5),i%5].imshow(w2p)  #axs[i,j]位于第i行第j列
  plt.show()

  model_2.fit(train_images,train_labels,epochs = 10)  #训练10次
  w0 = model_2.get_weights()[0]  #获取训练后权重
  fig,axs = plt.subplots(2,5,figsize = (15,5))  #绘制子图,画布大小15*5
  for i in range(10):
      w2p = w0[:,i].reshape(28,28)
      axs[int(i/5),i%5].imshow(w2p)  #axs[i,j]位于第i行第j列
  plt.show()
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值