是的,神经网络自己学习特征,使您无需手动设计它们。我将在这里用一个玩具问题来说明它。
假设我们想学习建立在向量对上的平行四边形的面积:
输入数据是六个坐标:(X1,是的1,X2,是的2,X3,是的3).
import numpy as np
n_tr = 1000 # training data
x_tr = np.random.uniform(low=-1.0, high=1.0, size=(n_tr, 6))
n_ts = 100 # test data
x_ts = np.random.uniform(low=-1.0, high=1.0, size=(n_ts, 6))
目标(区域)是是的= | 一个_- b c |, 在哪里a=x3−x1,b=y3−y1,c=x2−x1,d=y2−y1.
a_tr = x_tr[:,4] - x_tr[:,0] # x_3 - x_1
b_tr = x_tr[:,5] - x_tr[:,1] # y_3 - y_1
c_tr = x_tr[:,2] - x_tr[:,0] # x_2 - x_1
d_tr = x_tr[:,3] - x_tr[:,1] # y_2 - y_1
y_tr = np.abs(a_tr*d_tr-b_tr*c_tr)
a_ts = x_ts[:,4] - x_ts[:,0] # x_3 - x_1
b_ts = x_ts[:,5] - x_ts[:,1] # y_3 - y_1
c_ts = x_ts[:,2] - x_ts[:,0] # x_2 - x_1
d_ts = x_ts[:,3] - x_ts[:,1] # y_2 - y_1
y_ts = np.abs(a_ts*d_ts-b_ts*c_ts)
要从坐标中学习区域,我将使用我最喜欢的机器学习库super_magic_learn
from super_magic_learn import wonder_network
wonder_network.init()
它将在神经元中初始化一个具有随机激活函数的网络,并且它们之间的随机连接具有随机权重。它还随机分配一些神经元作为输入,而其他输出或内部神经元。

然后我训练我的网络
wonder_network.fit(x_tr, y_tr, use_wand=True)
在训练过程中,神经元内部的激活函数发生变化,神经元之间的连接形成、消失、再形成,并调整它们的权重。一些神经元分层组织,每一层的神经元个数发生变化,最终训练出的网络如下:

它以 100% 的准确率解决了训练和测试数据的任务,并且仅使用原始数据:坐标来解决任务。无需设计功能。
但是,您可能无权访问该库super_magic_learn
。让我们看看我们可以用稍微劣质的东西做什么tensorflow
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential(
[
layers.Dense(64, activation="tanh", input_dim=6),
layers.Dense(4, activation="tanh"),
layers.Dense(1),
]
)
optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001)
model.compile(loss='mean_squared_error',
optimizer=optimizer,
metrics=['mean_squared_error'])
model.fit(x_tr, y_tr, epochs=512, batch_size=64, validation_split = 0.2, verbose=1)
y_pr = model.predict(x_ts)
现在计算测试集的性能
from sklearn.metrics import r2_score
print('Rsq:', r2_score(y_ts,y_pr))
R2:
Rsq: 0.4802872880495598
不好。如果我设计一些功能会发生什么?
让我们训练相同的模型,但不是用原始数据输入它,输入将是以下手动设计的特征:a=x3−x1,b=y3−y1,c=x2−x1,d=y2−y1(不要忘记input_dim=4
在第一层进行更改)。
x_tr = np.c_[a_tr, b_tr, c_tr, d_tr]
x_ts = np.c_[a_ts, b_ts, c_ts, d_ts]
R2:
Rsq: 0.8841499533897564
现在好多了。不过还不到100%。
为什么神经网络在tensorflow
原始数据上表现不佳,需要特征工程,而super_magic_learn
在原始数据上表现完美,不需要任何特征工程?
原因是那个tensorflow
或我知道的任何其他图书馆都比我心爱的图书馆更受限制super_magic_learn
。限制如下(请注意一个非常小的问题:super_magic_learn
不存在,但我希望它存在):
- 您只有极少数的激活函数可供选择,例如 tanh、relu 和少数其他函数。
- 激活函数在训练期间保持不变。你不能改变它们。
- 您不能添加/删除图层。
- 您无法更改层中的神经元数量。
- 您不能添加/删除神经元之间的连接。
- 你必须只分层组织你的神经元,不允许其他排列。
- 在训练期间,网络无法学习到最适合该任务的架构。例如,考虑到问题的对称性,它不能重新组织自己。
- 等等 ...
- 基本上,您在训练期间唯一能做的就是学习权重。
教科书是对的:理想情况下,神经网络应该只从原始数据中学习。但这仅适用于我的理想化库,而不适用于现有的现实世界实现。
为了让网络真正学习任何任务的特征,它应该摆脱这些限制。
如果你对架构、激活函数和其他参数设置了如此多的限制,以至于在训练期间无法从数据中学习它们,那么你必须自己设计它们并为你的任务手动调整它们。如果您正确地设计它们,那么您的网络将从原始数据中愉快地学习。但它可能在其他任务上表现不佳。
卷积神经网络就是这种情况。它们的设计考虑了图像中特征的跨国等效性,这就是它们可以从原始图像数据中学习特征的原因。但是,它们不一定在其他领域表现良好。