具有不规则 data/variable 张量形状的机器学习算法
Machine Learning algorithm with irregular data/variable tensor shape
我想为粒子物理建立一个神经网络。我将评估假设 2000 个事件,这些事件中的粒子数量是可变的。但每个粒子有 5 个变量,因此形状为(2000,粒子数,5)。现在我已经设置了一个形状为 (2000,500,5) 的张量,第二维中不存在粒子的变量仅为 0。但我认为这是误导,因为它提高了网络的准确性,即使它是不是更准确。特别是当我正在搜索二进制输出时。现在我需要一个多类、单标签的分类。如何为可变输入维度设置图层?我的第一个方法方向错误吗?
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(500,5)))
model.add(tf.keras.layers.Dense(500*5, activation="relu"))
model.add(tf.keras.layers.Dense(1,activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.fit(INPUT, OUTPUT, epochs=10, batch_size=1)
为什么您可能需要另一种架构
阅读你的问题陈述后,听起来你正在 运行 模拟多达 500 个粒子,每个粒子都有类似 x、y、dx、dy 和质量属性(每个 5 个变量)
如果我要尝试手动解决 500 个 2D 粒子模拟,我可能会在 2D 中绘制粒子并从那里开始,因为 2D 格式对问题很有意义。或者,如果我们只是给一个有 500 行和 5 列数字的人一个电子表格,而不告诉他们这意味着什么,只是告诉他们弄清楚,我敢打赌他们会很难过。
继续这种直觉,现代机器学习现在特别擅长图像和二维数据,我建议将您的数据表示为二维网格,也许是 128x128x3 网格,其中 3 个值是总和该网格中的 dx、dy 和质量 space。这将允许您拥有任意数量的粒子。
粒子将与附近的其他粒子相互作用,而卷积对此有很大帮助。
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(128,128,3)))
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 64x54
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 32x32
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 16x16
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 8x8
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 4x4
model.add(tf.keras.layers.Conv2D(16, 4, activation="tanh", padding="valid"))
model.add(tf.keras.layers.Conv2D(2, 1, activation="softmax", padding="same"))
model.add(tf.keras.layers.Flatten())
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.fit(INPUT, OUTPUT, epochs=10)
您的输出现在是 2 个类别的 softmax。你可以训练它回答这样的问题:是否有两个靠近的粒子,是否有三个靠近的粒子,总质量是否大于 42。它可能无法回答这样的问题:总质量 angular顺时针方向的速度,所有的粒子最终都会发生碰撞。
为什么密集层可能不起作用
让我们再看看你当前的架构,看看它需要学习什么才能做得好
2) model.add(tf.keras.Input(shape=(500,5)))
3) model.add(tf.keras.layers.Dense(500*5, activation="relu"))
4) model.add(tf.keras.layers.Dense(1,activation="softmax"))
如果我们看第 3 行,它接受 500x5 输入(2,500 个浮点数)并对其执行密集的全连接操作以输出 2,500 个浮点数。这是一个具有 2,500 x 2,500 个参数 = 6,250,000 个参数的矩阵,每个参数对应输入到输出的每个组合。它必须学习其中的每一个。为了让大家注意到这有多困难,请想象一下您只有 4 个粒子 A、B、C 和 D 的情况。
如果你用ABCD、ACDB和ADBC这样排序的粒子训练模型,它将无法推广到BACD的新情况。从来没有见过B排在第一位,dense network没有泛化问题的机制。
将此与上面的卷积示例进行比较。每个卷积仅学习如何将 2d 世界的 5x5 块映射到下一个较小的层。 5x5 的补丁每个只接受 5x5 上的 16 个参数,并将其映射到 16 个输出,每层总共有 6,400 个参数。有 7 个卷积层(最后一对较小,但让我们忽略它)大约有 7 * 6,400 = 44,000 个参数。与600万相去甚远。此外,这些参数在每个位置一次又一次地重复使用,如果它们 'learn' 右上角的某个人,则该知识将应用于图像的每个部分。
你可以尝试打乱你的数据,让密集层在第 2 行工作,打乱 ABCD 的顺序,这样你就可以在每个位置训练每个粒子。对于500个位置,组合的数量是500个阶乘,因此计算不实用。
我想为粒子物理建立一个神经网络。我将评估假设 2000 个事件,这些事件中的粒子数量是可变的。但每个粒子有 5 个变量,因此形状为(2000,粒子数,5)。现在我已经设置了一个形状为 (2000,500,5) 的张量,第二维中不存在粒子的变量仅为 0。但我认为这是误导,因为它提高了网络的准确性,即使它是不是更准确。特别是当我正在搜索二进制输出时。现在我需要一个多类、单标签的分类。如何为可变输入维度设置图层?我的第一个方法方向错误吗?
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(500,5)))
model.add(tf.keras.layers.Dense(500*5, activation="relu"))
model.add(tf.keras.layers.Dense(1,activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.fit(INPUT, OUTPUT, epochs=10, batch_size=1)
为什么您可能需要另一种架构
阅读你的问题陈述后,听起来你正在 运行 模拟多达 500 个粒子,每个粒子都有类似 x、y、dx、dy 和质量属性(每个 5 个变量)
如果我要尝试手动解决 500 个 2D 粒子模拟,我可能会在 2D 中绘制粒子并从那里开始,因为 2D 格式对问题很有意义。或者,如果我们只是给一个有 500 行和 5 列数字的人一个电子表格,而不告诉他们这意味着什么,只是告诉他们弄清楚,我敢打赌他们会很难过。
继续这种直觉,现代机器学习现在特别擅长图像和二维数据,我建议将您的数据表示为二维网格,也许是 128x128x3 网格,其中 3 个值是总和该网格中的 dx、dy 和质量 space。这将允许您拥有任意数量的粒子。
粒子将与附近的其他粒子相互作用,而卷积对此有很大帮助。
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(128,128,3)))
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 64x54
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 32x32
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 16x16
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 8x8
model.add(tf.keras.layers.Conv2D(16, 5, activation="tanh", padding="same"))
model.add(tf.keras.layers.MaxPool2D(2)) # 4x4
model.add(tf.keras.layers.Conv2D(16, 4, activation="tanh", padding="valid"))
model.add(tf.keras.layers.Conv2D(2, 1, activation="softmax", padding="same"))
model.add(tf.keras.layers.Flatten())
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.fit(INPUT, OUTPUT, epochs=10)
您的输出现在是 2 个类别的 softmax。你可以训练它回答这样的问题:是否有两个靠近的粒子,是否有三个靠近的粒子,总质量是否大于 42。它可能无法回答这样的问题:总质量 angular顺时针方向的速度,所有的粒子最终都会发生碰撞。
为什么密集层可能不起作用
让我们再看看你当前的架构,看看它需要学习什么才能做得好
2) model.add(tf.keras.Input(shape=(500,5)))
3) model.add(tf.keras.layers.Dense(500*5, activation="relu"))
4) model.add(tf.keras.layers.Dense(1,activation="softmax"))
如果我们看第 3 行,它接受 500x5 输入(2,500 个浮点数)并对其执行密集的全连接操作以输出 2,500 个浮点数。这是一个具有 2,500 x 2,500 个参数 = 6,250,000 个参数的矩阵,每个参数对应输入到输出的每个组合。它必须学习其中的每一个。为了让大家注意到这有多困难,请想象一下您只有 4 个粒子 A、B、C 和 D 的情况。
如果你用ABCD、ACDB和ADBC这样排序的粒子训练模型,它将无法推广到BACD的新情况。从来没有见过B排在第一位,dense network没有泛化问题的机制。
将此与上面的卷积示例进行比较。每个卷积仅学习如何将 2d 世界的 5x5 块映射到下一个较小的层。 5x5 的补丁每个只接受 5x5 上的 16 个参数,并将其映射到 16 个输出,每层总共有 6,400 个参数。有 7 个卷积层(最后一对较小,但让我们忽略它)大约有 7 * 6,400 = 44,000 个参数。与600万相去甚远。此外,这些参数在每个位置一次又一次地重复使用,如果它们 'learn' 右上角的某个人,则该知识将应用于图像的每个部分。
你可以尝试打乱你的数据,让密集层在第 2 行工作,打乱 ABCD 的顺序,这样你就可以在每个位置训练每个粒子。对于500个位置,组合的数量是500个阶乘,因此计算不实用。