机器学习和人工智能技术在地学的各个领域得到了广泛研究和应用,包括岩土工程和采矿工程,例如建立地质模型【基于云机器学习算法的地质建模---Maptek Vulcan GeologyCore】和采矿控制【削壁充填采矿法(Narrow Vein Stoping)的发展】。在刚刚结束的第57届ARMA岩石力学会议上【ARMA年会明日召开 | 红狗矿(Red Dog Mine)的边坡稳定性调查】,除了Itasca举办的短期课程《Introduction to Machine Learning in Geomechanics》外,共提交了大约43篇与机器学习和人工智能相关的论文,本文首先总结了这些论文的主要应用领域,然后回顾了它们使用的机器学习方法,最后给出了流行的机器学习的通用代码(Tensorflow框架)。
在这43篇论文中,大约有20篇应用在石油和能源工程中,主要讨论钻探(Drilling)的预测,这是最热的研究方向;其次相对集中的应用领域是剪切波速预测(Shear Wave Velocity),大约有4~5篇论文,其余的则分布在传统的岩石力学应用领域,主要包括:
(1) 岩土数据处理(Linking High Resolution Geomechanical Datasets to Log Scale via Machine Learning);
(2) 断层损伤带(Prediction of Fault Damage Zones using ANNs);
(3) 隧道工程岩体条件(Advance prediction of rock mass conditions during TBM tunnelling based on cost-sensitive learning under imbalance dataset);
(4) 水力压裂(A Machine Learning based proxy model for the rapid prediction of hydraulic fractures);
(5) 孔隙压力(Real-time Prediction of Formation Pore Pressure using Hybrid LSTM-BP model; Neural network model to predict pore pressure and wellbore stability from LWD log and drilling parameter);
(6) 岩爆(An optimized deep neural network for rockburst damage potential modelling);
(7) 岩石力学参数(Machine Learning Based Predictive Models for UCS and Young’s Modulus of the Dakota Sand Using Schmidt Hammer Rebound);
(8) 岩石断裂(Experimental study of tight reservoir rock failure process based on unsupervised machine learning; Fracture pressure prediction by using the LSTM neural network model);
(9) 原岩应力(Prediction of in-situ stresses by using machine learning and intelligent optimization algorithms);
(10) 岩石破碎(Combining Machine Learning and Physics Modelling to Determine the Natural Cave Property with Fracturing Curves);
(11) 地面沉降(Predicting ground surface deformation induced by pressurized fractures using conditional generative adversarial networks)
(12) 滑坡(Comparative Study of Machine Learning Vs. BIS Approach For Landslide Hazard Zonation in Kashmir Himalayas, India)
(13) 爆破(Blast Movement Simulation through a Hybrid Approach of Continuum, Discontinuum, and Machine Learning Modeling)
纵观这43篇论文,除了使用传统的人工神经网络外,主要使用了三种流行的机器学习方法:RNN, GRU和LSTM。下面简要回顾了这三种方法的原理。
递归神经网络(Recurrent Neural Networks)旨在处理顺序数据,例如时间序列。在RNN中,层中所有节点的权重和偏差是相同的。RNN面临的短期记忆问题。这是由于梯度消失问题引起的。随着RNN处理更多的步骤,它比其他神经网络架构更容易遭受梯度消失的影响。
在RNN中,为了训练随着时间的推移反向传播的网络,在每一步都会计算梯度。梯度用于更新网络中的权重。如果前一层对当前层的影响很小,则梯度值将很小,反之亦然。如果前一层的梯度较小,则当前层的梯度将更小。这使得梯度在反向传播时呈指数级缩小。较小的梯度意味着它不会影响重量更新。因此网络不会学习早期输入的效果。所以导致短期记忆问题。为了克服RNN的短期记忆问题,提出了下面的两种改进方法。
3.2 门控递归单元GRU
门控递归单元(Gated Recurrent Units)的工作流程与RNN相同,但区别在于GRU单元内部的操作。在GRU内部,它有两个门:复位门和更新门,每个门都有自己的权重和偏差,更新门决定是否应使用候选状态(当前激活值)更新单元格状态, 而复位门用于确定以前的单元状态是否重要。
3.3 长短期记忆LSTM
长短期记忆(Long Short-Term Memory)LSTM在GRU的基础上进行了改进,也旨在解决梯度消失问题。除了GRU之外,增加了两个门:忘记门和输出门。忘记门控制从以前的单元格状态保留与遗忘的内容。通俗地说,它将决定应该保留多少来自先前状态的信息并忘记剩余的信息。输出门控制将单元格的哪些部分输出到隐藏状态。它将确定下一个隐藏状态是什么。
4 机器学习代码
机器学习的框架有两个:一个是Pytorch,另一个是TensorFlow 。下面的通用代码使用的是Tensorflow,用来进行RNN,GRU和LSTM的训练,可以应用在任何领域。
(1) 导入机器学习库
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,LSTM,GRU,SimpleRNN
from sklearn.preprocessing import MinMaxScaler
(2) 建立数据集
df = pd.read_csv('dataset.csv')
dataset = np.array(df)
scaler = MinMaxScaler()
dataset = scaler.fit_transform(dataset)
(3) 划分数据集
train_size = int(len(dataset) * 0.75)
test_size = len(dataset) - train_size
train=dataset[:train_size,:]
test=dataset[train_size:142,:]
def getdata(data,lookback):
X,Y=[],[]
for i in range(len(data)-lookback-1):
X.append(data[i:i+lookback,0])
Y.append(data[i+lookback,0])
return np.array(X),np.array(Y).reshape(-1,1)
lookback=1
X_train,y_train=getdata(train,lookback)
X_test,y_test=getdata(test,lookback)
X_train=X_train.reshape(X_train.shape[0],X_train.shape[1],1)
X_test=X_test.reshape(X_test.shape[0],X_test.shape[1],1)
(4) 神经网络布置
model=Sequential()
model.add(LSTM(5,input_shape=(1,lookback)))
model.add(Dense(1))
model.compile(loss='mean_squared_error',optimizer='adam')
(5) 训练
model.fit(X_train, y_train, epochs=50, batch_size=1)
y_pred=model.predict(X_test)
y_test=scaler.inverse_transform(y_test)
y_pred=scaler.inverse_transform(y_pred)