应用篇:神经网络用于预测模型

1.高熵合金晶界预测

1.导入数据

1.数据读取

  import pandas as pd
  df = pd.read_csv('HEA.csv',header = 1).iloc[:-8,6:18]  #导入数据,header=1从第2行开始导入,iloc[]获取有用数据
  df.columns = ['T','Co','Ni','Cr','Fe','Mn','Co ad','Ni ad','Cr ad','Fe ad','Mn ad','Dis']  #重新命名列标签
  print(df)

2.预处理

  x = df.iloc[:,:-6].values  #提取数据
  y = df['Cr ad'].values
  y = y.astype('float64')  #将字符串转换为浮点数

  利用均值与标准差标准化数据
x ⟶ x − μ σ x\longrightarrow \frac{x-\mu}{ \sigma } xσxμ

  from sklearn.preprocessing import StandardScaler
  ss_x = StandardScaler()  #制作标准化器
  x_s = ss_x.fit_transform(x)  #标准化
  ss_y = StandardScaler()
  y_s = ss_y.fit_transform(y.reshape(-1,1)).reshape(-1)  #将一行数据转换一列数据,之后再转换一行数据
  print(x_s,y_s)

3.切分训练集

  from sklearn.model_selection import train_test_split
  # 数据集切训练集(0.7)、测试集(0.15)、验证集(0.15)
  x_train,x_test,y_train,y_test = train_test_split(x_s,y_s,test_size = 0.15)
  x_train,x_validation,y_train,y_validation = train_test_split(x_train,y_train,test_size = 0.1765)
  print(x_train.shape,x_validation.shape,x_test.shape)
2.模型构建

1.Keras模型构建方法
Keras模型构建方法
2.三种模型方法对比

方法序贯模型函数式模型模型子类化
损失函数0.08740.08130.0781
准确率97.82%98.06%98.20%

  三种方法的底层设计有细微的差别,通常这样的差别可以忽略不计

3.序贯模型与函数式API模型

1.序贯模型的构建

  from tensorflow import keras
  model_seq = keras.Sequential([  #构建网络
      keras.Input(shape=(6)),
      keras.layers.Dense(20,activation = 'relu'),  #使用relu激活函数
      keras.layers.Dense(1)
  ])
  print(model_seq.summary())

2.函数型模型的构建

  layer_input = keras.Input(shape=(6))  #输入层
  layer_hidden = keras.layers.Dense(20,activation = 'relu')(layer_input) #连接到输入层之下
  layer_output = keras.layers.Dense(1)(layer_hidden)  #连接到隐藏层之下
  model = keras.Model(inputs = layer_input,outputs = layer_output)  #构建函数型模型
  print(model.summary())

3.编译与训练

  adam = keras.optimizers.Adam(learn_rate = 0.001)  #学习率0.001,Adam优化
  model.complie(lose = 'mse',optimizer = adam,metrics = ['mse'])
  history = keras.callbacks.History()  #History 回调函数
  model.fit(x_train,y_train,validation_data = (x_validation,y_validation),
            epochs = 500,callbacks = [history],verbose = 0)  #验证集手动给出,训练500次,不输出

4.模型评价

  from sklearn.metrics import r2_score
  import numpy as np
  def model_predict(model,x_data,y_data,ss):  #自定义函数,模型预测,预测后数据逆标准化
      result = model.predict(x_data)  #模型预测
      y_pred = ss.inverse_transform(result).reshape(-1)  #逆标准化
      y_real = ss.inverse_transform(y_data.reshape(-1,1)).reshape(-1)
      return y_real,y_pred

  y_real_train,y_pred_train = model_predict(model,x_train,y_train,ss_y)  #计算模型预测值
  y_real_validation,y_pred_validation = model_predict(model,x_validation,y_validation,ss_y)
  y_real_test,y_pred_test = model_predict(model,x_test,y_test,ss_y)

  def compute_mae_mse_rmse(real,pred):  #自定义计算平均绝对误差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_real_train * 100,y_pred_train *100) #计算误差
  error_val_validation = compute_mae_mse_rmse(y_real_validation * 100, y_pred_validation * 100)
  error_val_test = compute_mae_mse_rmse(y_real_test * 100, y_pred_test * 100)

  模型训练结果

  print('train mae: %.3f,mse: %.3f,rmse: %.3f,r2: %4f'%(error_val_train[0],error_val_train[1],
                                                          error_val_train[2],error_val_train[3]))  #输出误差
  print('validation mae: %.3f,mse: %.3f,rmse: %.3f,r2: %4f'%(error_val_validation[0],error_val_validation[1],
                                                          error_val_validation[2],error_val_validation[3]))
  print('test mae: %.3f,mse: %.3f,rmse: %.3f,r2: %4f'%(error_val_test[0],error_val_test[1],
                                                          error_val_test[2],error_val_test[3]))
4.数据可视化

1.绘制预测散点图

  import matplotlib.pyplot as plt
  plt.figure(figsize = (6,6))  #设置画布大小,绘制预测散点图
  plt.scatter(y_real_train *100,y_pred_train *100,s = 100,  #训练集,大小100,金黄色
              color = 'goldenrod',label = 'Traing Set')
  plt.scatter(y_real_validation *100,y_pred_validation *100,s = 100,  #验证集,大小100,浅蓝色
              color = 'lightblue',label = 'Validation Set')
  plt.scatter(y_real_test *100,y_pred_test *100,s = 100,  #测试集,大小100,紫色
              color = 'purple',label = 'Testing Set')
  plt.plot([0,65],[0,65],color = 'grey',linestyle = '--',linewidth = 3)  #绘制对角线,虚线,宽度3,灰色
  plt.legend()  #显示图例
  plt.xlim(0,65)  # x y轴坐标范围
  plt.ylim(0,65)
  plt.xlabel('MC/MD')  # x y轴标签
  plt.ylabel('ANN')
  plt.show()

2.绘制预测相图

  x_pred = []  #构建待预测数组
  for T in np.arange(1000,1310,10):  #温度T
      for i in np.arange(0.0,0.4,0.02):  #Mn的浓度
          j = 0.4 - i  # Cr的浓度
          xx = []  #构建一组数据
          xx.append(T)  #温度
          xx.append(0.2)  #Co浓度
          xx.append(0.2)  #Ni浓度
          xx.append(j)  #Cr浓度
          xx.append(0.2)  #Fe浓度
          xx.append(i)  #Mn浓度
          x_pred.append(xx)

  x_pred = np.array(x_pred)  #转换为数组
  x_pred_nor = ss_x.transform(x_pred)  #标准化
  y_pred_nor = model.predict(x_pred_nor)  #模型预测
  y_pred = ss_y.inverse_transform(y_pred_nor).reshape(-1)  #逆标准化

  # 绘制相图
  x0,y0 = np.meshgrid(np.arange(0.0,0.4,0.02),np.arange(1000,1310,10))  #生成坐标矩阵
  plt.figure(figsize = (6,5))  #设置画图大小
  levels = np.linspace(-10,50,101)  #-10和50是色阶显示的数据范围,101是颜色显示的细致程度
  plt.contourf(x0,y0,y_pred.reshape(x0.shape)*100,cmap = 'bwr',levels = levels)  #contourf()绘制二维颜色填充图,
  plt.xticks(np.arange(0.05,0.36,0.1))  # x y轴刻度值
  plt.yticks(np.arange(1000,1301,100))
  plt.xlim(0.05,0.35) # x y轴范围
  plt.ylim(1000,1300)
  plt.xlabel('X Mn')  # x y轴标签
  plt.ylabel('T(K)')
  cb = plt.colorbar()  #储存颜色条
  cb.set_ticks([0,10,20,30,40,50])  #设置颜色条刻度
  plt.show()
5.训练曲线
  #绘制训练曲线
  plt.plot(history.history['loss'],label = 'train')
  plt.plot(history.history['val_loss'],label = 'validation')
  plt.legend()  #显示图例
  plt.xlabel('Epoch')  # x y轴标签
  plt.ylabel('Loss')
  plt.show()

1.欠拟合曲线
  模型在训练集上无法得到足够低的误差
2.过拟合曲线
  验证集损失减小到一个点再次开始增加
3.好的拟合曲线
  模型在训练集和验证集上的性能都很好
  训练和验证损失共同减少并稳定在同一点附近

2.用DOS预测吸附能

1.导入数据

1.序列化与反序列化

  #二进制序列化
  import pickle
  list_1 = ['Fe','Co','Ni']
  with open('list_1.pkl','wb') as f:
      pickle.dump(list_1,f)
  #序列化
  with open('list_1.pkl','rb') as f:
      list_2 = pickle.load(f)
  print(list_2)

2.数据导入

  import pickle
  with open('OH_data',mode = 'rb') as f:  #数据反序列化
      surface_dos = pickle.load(f)  #DOS
      targets = pickle.load(f)  #吸附能

3.查看数据样本

  import matplotlib.pyplot as plt
  for i in range(1,10):  #查看数据样本
      plt.plot(surface_dos[0,:-500,0],surface_dos[0,:-500,i])
  plt.show()

4.数据预处理

  import numpy as np
  from sklearn.model_selection import train_test_split
  from sklearn.preprocessing import StandardScaler
  surface_dos = surface_dos[:,:2000,1:28]  #截取处理
  surface_dos[:,1800:2000,0:27] = 0
  surface_dos = surface_dos.astype(np.float32)  #数据类型准换

  ss_x = StandardScaler()  #制作标准化器
  x_s = ss_x.fit_transform(surface_dos.reshape(-1,surface_dos.shape[2])).reshape(surface_dos.shape)  #x标准化
  y = targets
  x_train,x_test,y_train,y_test = train_test_split(x_s,y,test_size = 0.2) #划分为训练集和测试集,比例0.2
  • 标准化 StandardScaler()
    x s = x − μ σ x_{s}=\frac{x-\mu}{\sigma} xs=σxμ
  • 归一化 MinMaxScaler()
    x n = x − x m i n x m a x − x m i n x_{n}=\frac{x-x_{min}}{x_{max}-x_{min}} xn=xmaxxminxxmin
2.模型准备

1.池化(pool),卷积(conv)

  • 池化(平均值池化)
    AveragePooling1D(pool_size,strides,padding)
    pool_size:池化窗口大小
    strides:步长,对应池化前后数据量比例
    padding:控制输出层的大小,‘valid’,‘same’
    v a l i d : s h a p e ( i n p u t ) − s h a p e ( p o o l ) + 1 s t r i d e s valid:\frac{shape\left(input\right)-shape\left(pool\right)+1}{strides} valid:stridesshape(input)shape(pool)+1
    s a m e : s h a p e ( i n p u t ) s t r i d e s same:\frac{shape\left(input\right)}{strides}\quad\quad\quad\quad\quad\quad\quad\quad same:stridesshape(input)
      池化层没有参数:在保证数据特征的同时减少了参数,可以减小计算量和预防过拟合。
  • 卷积
    Conv1D(filters,kernel_size,activation,padding,strides)
    filters:卷积核数量
    kernel_size:卷积窗口长度
    activation:激活函数
    padding:控制输出层,'valid’不填充,'same’填充
    strides:卷积步长

    卷积核
    Glorot正态分布初始化器,即高斯分布的初始化
N ( 0 , 2 n i n + n o u t ) μ = 0 , σ = 2 n i n + n o u t N\left(0,\sqrt{\frac{2}{n_{in}+n_{out}}}\right)\quad\quad\mu=0,\sigma=\sqrt{\frac{2}{n_{in}+n_{out}}} N(0,nin+nout2 )μ=0,σ=nin+nout2
    卷积核作用后,再使用激活函数调整

  import tensorflow as tf
  from tensorflow import keras
  from tensorflow.keras import layers
  from tensorflow.keras.layers import Input,BatchNormalization,Dropout,Dense
  from tensorflow.keras.layers import AveragePooling1D,Concatenate,Conv1D,Flatten
  channels = 9  #通道数
  def dos_featurizer(channels):  #特征化,减少计算量
      input_dos = Input(shape = (2000,channels))  #输入层
      x1 = AveragePooling1D(pool_size = 4,strides = 4,padding = 'same')(input_dos)  #平均值池化,池化窗口pool_size,步长strides,'same'自动补齐
      x2 = AveragePooling1D(pool_size = 25,strides = 4,padding = 'same')(input_dos)
      x3 = AveragePooling1D(pool_size = 200,strides = 4,padding = 'same')(input_dos)
      x = Concatenate(axis = -1)([x1,x2,x3])  #axis=-1 按最后一个维度拼接

      x = Conv1D(50,20,activation = 'relu',padding = 'same',strides = 2)(x)  #卷积,卷积核数量50,卷积窗口大小20,激活函数relu
      x = BatchNormalization()(x)  #批标准化
      x = Conv1D(75, 3, activation='relu', padding='same', strides=2)(x)  # 卷积
      x = AveragePooling1D(pool_size=3, strides=2, padding='same')(x)  # 平均值池化
      x = Conv1D(100, 3, activation='relu', padding='same', strides=2)(x)  # 卷积
      x = AveragePooling1D(pool_size=3, strides=2, padding='same')(x)  # 平均值池化
      x = Conv1D(125, 3, activation='relu', padding='same', strides=2)(x)  # 卷积
      x = AveragePooling1D(pool_size=3, strides=2, padding='same')(x)  # 平均值池化
      x = Conv1D(150, 3, activation='relu', padding='same', strides=1)(x)  # 卷积
      shared_model = Model(input_dos,x)  #构建共享模型
      return shared_model

2.独立同分布假设(independent and identically distributed,IID)
  监督训练的假设,假设训练数据与测试数据满足相同分布
  用于保证通过训练数据得到的模型在测试数据上能有良好表现
3.偏移
  数据集偏移(Dataset shfit):训练数据与待预测数据的分布不同
  输入分布偏移(Covariate shift):特殊的数据集偏移,训练数据与待预测数据条件概率相同但边缘概率不同
4.Internal Covariate Shift(ICS)
  在深层网络的训练过程中,网络参数的变化引起内部节点数据分布变化的现象
  ICS结果导致输入(in)与输出(out)条件概率相同但边缘概率不同
5.白化(Whitening)
  一种数据标准化的方法,常用的PCA白化(均值为0,方差为1)和ZCA白化(均值为0,方差相同)
  缺点:计算成本高,每层都需要白化,改变每一层的分布
6.批标准化
  对于B={x1,2,…,m}中的所有x
  mini-batch的均值:
μ B ← 1 m ∑ i = 1 m x i \mu_{B}\gets\frac{1}{m}\sum_{i=1}^{m}x_{i} μBm1i=1mxi
  mini-batch的方差:
σ B 2 ← 1 m ∑ i = 1 m ( x i − μ B ) 2 \sigma_{B}^{2}\gets\frac{1}{m}\sum_{i=1}^{m}\left(x_{i}-\mu_{B}\right)^{2} σB2m1i=1m(xiμB)2
  标准化:
x i ^ ← x i − μ B σ B 2 + ε \hat{x_{i}}\gets\frac{x_{i}-\mu_{B}}{\sqrt{\sigma_{B}^{2}+\varepsilon }} xi^σB2+ε xiμB
  缩放与平移:
y i ← γ x ^ i + β ≡ B N γ , β ( x i ) y_{i}\gets\gamma\hat{x}_{i}+\beta\equiv BN_{\gamma,\beta}\left(x_{i}\right) yiγx^i+βBNγ,β(xi)

  对网络的参数 X 进行缩放,得 α \alpha αX
  缩放前:输入值 X   均值 μ \mu μ    方差 σ \sigma σ2
  缩放后:输入值 α \alpha αX  均值 α μ \alpha\mu αμ  方差 α \alpha α2 σ \sigma σ2
B N ( α X ) = γ α X − α μ α 2 σ 2 + β = γ X − μ σ 2 + β = B N ( X ) BN\left(\alpha X\right)=\gamma\frac{\alpha X-\alpha\mu}{\sqrt{\alpha^{2}\sigma^{2}}}+\beta=\gamma\frac{X-\mu}{\sqrt{\sigma^{2}}}+\beta=BN\left(X\right) BN(αX)=γα2σ2 αXαμ+β=γσ2 Xμ+β=BN(X)
  缩放对BN层输出没有影响

3.构建模型

1.模型构建

  from tensorflow.keras.models import Model
  from tensorflow.keras.optimizers import Adam
  def create_model(shared_conv,channels):  #自定义创建模型函数
      input1 = Input(shape = (2000,channels))  #输入层
      input2 = Input(shape=(2000, channels))
      input3 = Input(shape=(2000, channels))

      conv1 = shared_conv(input1) #创建共享模型
      conv2 = shared_conv(input2)
      conv3 = shared_conv(input3)

      convmerge = Concatenate(axis = -1)([conv1,conv2,conv3])  #axis=-1 按最后一个维度拼接
      convmerge = Flatten()(convmerge)  #降为一维数组
      convmerge = Dropout(0.2)(convmerge)  #预防过拟合,丢弃法,每次丢掉0.2的神经元
      convmerge = Dense(200,activation = 'linear')(convmerge)  #隐藏层,200个神经元
      convmerge = Dense(1000, activation='relu')(convmerge)  # 隐藏层,200个神经元
      convmerge = Dense(1000, activation='relu')(convmerge)  # 隐藏层,200个神经元

      out  = Dense(1)(convmerge)  #输出层
      model = Model(inputs = [input1,input2,input3],outputs = out)  #构建模型
      return model

  share_conv = dos_featurizer(channels)
  model = create_model(share_conv,channels) #创建模型
  print(model.summary())
  model.compile(loss = 'logcosh',optimizer = Adam(0.001),metrics = ['mean_absolute_error'])  #设置模型,学习率0.001

2.模型训练

  model.fit(  #训练模型
      [x_train[:,:,0:9],x_train[:,:,9:18],x_train[:,:,18:27]],  #输入
      y_train,batch_size = 128,epochs = 60,verbose = 0,  #输出,训练60次,不输出,batch_size=128,128个数据为一组
      validation_data = ([x_test[:,:,0:9],x_test[:,:,9:18],x_test[:,:,18:27]],y_test)  #验证集
  )
4.结果可视化
  #结果可视化
  train_out = model.predict([x_train[:,:,0:9],x_train[:,:,9:18],x_train[:,:,18:27]])  #模型预测
  test_out = model.predict([x_test[:,:,0:9],x_test[:,:,9:18],x_test[:,:,18:27]])
  train_out,test_out = train_out.reshape(len(train_out)),test_out.reshape(len(test_out))  #列数组改为行数组

  plt.figure(figsize = (6,6))  #画布大小
  plt.plot([-3,3],[-3,3])  #绘制对角线
  plt.scatter(y_train,train_out,s = 10,c = 'b')  #训练集
  plt.scatter(y_test,test_out,s = 10,c = 'r',alpha = 0.5)  #验证集
  plt.xlabel('DFT(eV)')  # x y标签
  plt.ylabel('ML Predicted(eV)')
  plt.axis([-3,3,-3,3])  #坐标轴范围
  plt.show()
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值