神经网络会找到什么模式?

在这篇文章中,我想谈谈神经网络可以找到的模式。 许多针对初学者的指南都侧重于为神经网络编写代码的技术,而“逻辑”问题(神经网络能做什么?哪种体系结构更适合于哪些任务,为什么?)通常处于观望状态。 希望我的帖子可以帮助初学者更好地了解神经网络的功能。 为此,我们将尝试看看它们如何处理某些模型任务。 将使用keras库在python中提供示例代码。

任务1.让我们从一个简单的例子开始。 我们构造一个近似正弦的神经网络。

import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, np.pi, n) y = np.sin(X) return X, y n = 40 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(6, input_dim=1, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=1000, batch_size=4) X_test = np.linspace(start=0, stop=np.pi, num=500) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Sinus approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show() 

我们得到以下图表:



如您所见,神经网络成功地完成了逼近简单函数的任务。

任务2。让我们看看神经网络将如何处理更复杂的任务。 我们将输入均匀分布在间隔[0,1]上的x值,并且y将被随机设置:对于x <0.6,y将是一个随机变量,其值为0,概率为0.75,1为概率为0.25(即,一个二项式随机值,其值为p = 0.25)。 对于x> 0.6,y将是一个随机变量,其值为0的概率为0.3,值为1的概率为0.7。 作为优化功能,我们采用标准误差。

 import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, 1, n) y0 = np.random.binomial(size=n, n=1, p=0.25) y1 = np.random.binomial(size=n, n=1, p=0.7) y = np.where(X < 0.6, y0, y1) return X, y n_inputs = 1 n_hidden1 = 100 n_hidden2 = 50 n_outputs = 1 n = 2000 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(n_hidden1, input_dim=1, activation='relu')) model.add(Dense(n_hidden2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy']) model.fit(X, y, epochs=200, batch_size=100) X_test = np.linspace(start=0, stop=1, num=100) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Binomial distribution approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show() 

我们得到以下近似函数神经网络图:



如您所见,神经网络近似了我们的随机变量y的数学期望。 因此,神经网络可以(原则上)近似于取决于参数的随机变量的平均值。 例如,我们可以期望他们解决以下问题:收入不超过$ 1,000的人们平均不满意,而收入超过$ 1,000的人们平均不满意; 必须学会根据收入来预测“幸福程度”。 神经网络将能够找到幸福的平均水平对收入的依赖关系,尽管事实上,在任何收入水平的人中,幸福和不幸福并存。

问题3。现在我们转向序列的预测。 我们将考虑由以下规则给定的0和1的序列:10个成员-可能为0或1,如果前一项为0,则第11个等于1,如果前一项为1,则第11个等于0或1。我们将生成这样的长度为11的序列(10个输入序列成员和一个(最后一个,我们预测),并在我们的递归神经网络上对其进行训练。 在训练之后,让我们检查一下她如何应对新序列的预测(长度为11)。

 import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense def get_X_y(m, n): X = np.random.binomial(size=(m,n), n=1, p=0.5) y0 = np.ones(m) y1 = np.random.binomial(size=m, n=1, p=0.5) y = np.where(X[:, n-1]==0, y0, y1) X = np.reshape(X, (X.shape[0], X.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=50)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000, 10) model.fit(X_train, y_train, epochs = 20, batch_size = 32) m_test = 12 n_test = 10 X_test, y_test = get_X_y(m_test, n_test) y_predicted = model.predict(X_test) for i in range(m_test): print("x_last=", X_test[i, n_test-1, 0], "y_predicted=", y_predicted[i, 0]) 

让我们看看我们的神经网络对测试序列的预测结果(您的结果将有所不同,因为在这里,序列选择和训练神经网络都存在随机性)。

序号序列的倒数第二个成员预测值
1个00.96
200.95
300.97
400.96
500.96
61个0.45
700.94
81个0.50
900.96
101个0.42
111个0.44
1200.92


如您所见,如果序列的倒数第二个成员为0,则神经网络会预测一个接近1的值,如果它为1,则接近0.5的值。 这接近最佳预测。 来自“生活”的类似示例可能看起来像这样:“如果我今天去电影院,那么明天我将在一家餐馆吃午餐; 如果我今天去剧院,那么明天我将在任何地方吃午饭。” 如我们所见,神经网络可以捕获这种类型的信息,并通过去看电影(并去剧院去预测“介于两者之间”)来预测去餐馆的行程。

任务4:我们使神经网络的任务复杂化。 假设一切都与前面的示例相同,则仅序列的第11个成员不是由序列的前一个成员而是由序列的第二个成员(通过相同规则)确定的。 我们在这里不提供代码,因为它实际上与上一个没有区别。 我的实验表明,神经网络仍然可以找到一种模式,但是需要更多的时间(我必须使用100个历元而不是20个历元进行训练)。
因此,神经网络可以(再次从原理上澄清)捕获相当长期的依赖关系(在我们的“生活示例”中,它们可以捕获诸如“如果我一周前去看电影,今天就去餐馆”等模式)。

任务5:让我们看看神经网络如何使用可用信息进行预测。
为此,我们将对长度为4的序列进行训练。总共,我们将具有3个不同的等概率序列:

0, 0, 1, 1
0, 1, 0, 1
0, 1, 1, 0


因此,在初始组合为0、0之后,我们总是会遇到两个单位,在组合为0、1之后,我们同样有可能满足0或1,但是我们肯定会知道最后一个数字。 现在,我们将通过设置return_sequences = True来要求神经网络返回序列。 作为预测序列,我们将相同的序列移动一级,并在右侧添加零。 现在我们已经可以假设会发生什么:第一步,神经网络将产生一个接近2/3的数字(由于第二项的概率为2/3,因此第二项是1),然后对于0的组合,它将产生两个接近单位,对于0,1首先将给出接近0.5的数字,然后将给出接近0或1的数字,具体取决于我们是否获得序列0、1、0或0、1、1。在神经网络的末尾总是会产生接近0的数字。通过检查以下代码,我们的假设是正确的。

 import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense import random def get_X_y(n): X = np.zeros((n, 4)) z = np.array([random.randint(0, 2) for i in range(n)]) X[z == 0, :] = [0, 0, 1, 1] X[z == 1, :] = [0, 1, 0, 1] X[z == 2, :] = [0, 1, 1, 0] y = np.zeros((n, 4)) y[:, :3] = X[:, 1:] X = np.reshape(X, (X.shape[0], X.shape[1], 1)) y = np.reshape(y, (y.shape[0], y.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=20, return_sequences=True)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000) model.fit(X_train, y_train, epochs = 100, batch_size = 32) X_test = np.zeros((3, 4)) X_test[0, :] = [0, 0, 1, 1] X_test[1, :] = [0, 1, 0, 1] X_test[2, :] = [0, 1, 1, 0] X_test = np.reshape(X_test, (3, 4, 1)) y_predicted = model.predict(X_test) print(y_predicted) 


从这个例子中,我们看到神经网络可以根据收到的信息动态地改变预测。 我们会做同样的事情,尝试预测一个特定的顺序:当可用信息允许我们估计下一步结果的概率时,我们将基于此信息进行预测; 但是当我们在下一步中找到其他信息时,我们会根据此信息更改预测。
因此,如果我们发现有人从黑暗中来找我们,那么我们说:“这是一个人,我们不知道更多”。 当我们开始在黑暗中区分长发时,我们说“这可能是一个女人”。 但是,如果在那之后我们认为一个人有胡须,那么我们就说这可能是一个男人(尽管留着长发)。 如我们所见,神经网络的行为类似,使用当前可用的全部信息进行预测。

因此,我们看了神经网络如何工作以及可以找到哪些模式的简单示例。 总的来说,我们看到神经网络的行为通常是“合理的”,从而使预测接近人的预测。 尽管应该指出,为了捕捉简单的模式,它们需要的数据比人多得多。

Source: https://habr.com/ru/post/zh-CN467895/


All Articles