python - 未在 PyGAD 中训练二元分类 NN 模型权重
问题描述
这是我正在编写的代码: 假新闻检测 Google Colab Notebook
我使用的数据集: fake_or_real_news
手套嵌入层: glove.twitter.27B.200d
我一直在尝试 PyGAD,这是一个用于机器学习的遗传算法的 Python 库。
我想要实现的是假新闻检测。我所做的是对文章进行预处理,并将它们转换为向量。我使用 Glove 作为 NN 中的嵌入层。我尝试在没有 GA 的情况下使用 NN 模型进行训练,并且效果很好。然后我按照教程将 NN 应用于 PyGAD GA:如何使用 PyGAD 的遗传算法训练 Keras 模型,这个过程似乎运行良好,但即使经过 200 代,适应度得分也没有上升。我试图改变突变方法和其他一些超参数,但它似乎并没有改变结果。我在构建 PyGAD GA 模型的过程中做错了什么?大多数 PyGAD 模型设置与上面教程中的示例相同。
指定我遇到的问题:下面是我正在使用的主要 PyGAD 代码:
训练输入(X_train):
array([[ 4981, 2484, 22458, ..., 1019, 135, 892],
[ 7075, 189, 26439, ..., 4982, 43, 2],
[ 6168, 335, 2, ..., 73, 27, 73],
...,
[ 374, 10, 162, ..., 736, 1744, 484],
[ 500, 118, 2, ..., 348, 2890, 5689],
[ 8194, 2404, 117, ..., 357, 6332, 186]], dtype=int32)
shape: (3753, 50)
训练输出(y_train):
array([[1., 0.],
[0., 1.],
[0., 1.],
...,
[0., 1.],
[1., 0.],
[0., 1.]], dtype=float32)
shape: (3753, )
Python代码:
import tensorflow.keras
import pygad.kerasga
import numpy
import pygad
def fitness_func(solution, sol_idx):
global data_inputs, data_outputs, keras_ga, model
model_weights_matrix = pygad.kerasga.model_weights_as_matrix(model=model, weights_vector=solution)
model.set_weights(weights=model_weights_matrix)
predictions = model.predict(data_inputs)
bce = tensorflow.keras.losses.BinaryCrossentropy()
solution_fitness = 1.0 / (bce(data_outputs, predictions).numpy() + 0.00000001)
return solution_fitness
def callback_generation(ga_instance):
print("Generation = {generation}".format(generation=ga_instance.generations_completed))
print("Fitness = {fitness}".format(fitness=ga_instance.best_solution()[1]))
sequence_length = X_train.shape[1]
filter_sizes = [3,4]
num_filters = 100
drop = 0.4
#the NN
inputs = Input(shape=(sequence_length,))
embedding = embedding_layer(inputs)
reshape = Reshape((sequence_length,EMBEDDING_DIM,1))(embedding)
conv_0 = Conv2D(num_filters, (filter_sizes[0], EMBEDDING_DIM),activation='relu',kernel_regularizer=regularizers.l2(0.01))(reshape)
conv_1 = Conv2D(num_filters, (filter_sizes[1], EMBEDDING_DIM),activation='relu',kernel_regularizer=regularizers.l2(0.01))(reshape)
maxpool_0 = MaxPooling2D((sequence_length - filter_sizes[0] + 1, 1), strides=(1,1))(conv_0)
maxpool_1 = MaxPooling2D((sequence_length - filter_sizes[1] + 1, 1), strides=(1,1))(conv_1)
merged_tensor = concatenate([maxpool_0, maxpool_1], axis=1)
flatten = Flatten()(merged_tensor)
reshape = Reshape((2*num_filters,))(flatten)
dropout = Dropout(drop)(flatten)
conc = Dense(40)(dropout)
output = Dense(units=2, activation='sigmoid',kernel_regularizer=regularizers.l2(0.01))(conc)
#create model
model = Model(inputs, output)
keras_ga = pygad.kerasga.KerasGA(model=model, num_solutions=10)
# Data inputs
data_inputs = X_train
# Data outputs
data_outputs = y_train
data_outputs = tensorflow.keras.utils.to_categorical(data_outputs)
num_generations = 200
num_parents_mating = 8
initial_population = keras_ga.population_weights
ga_instance = pygad.GA(num_generations=num_generations,
num_parents_mating=num_parents_mating,
initial_population=initial_population,
fitness_func=fitness_func,
on_generation=callback_generation,
)
ga_instance.run()
这是我在 ga_instance.run() 之后得到的结果:
Generation = 1
Fitness = 1.4091019376092528
Generation = 2
Fitness = 1.4091019376092528
...
Generation = 200
Fitness = 1.4091019376092528
预测结果:
Ground Truth:
array([[1., 0.],
[0., 1.],
[0., 1.],
...,
[0., 1.],
[1., 0.],
[0., 1.]], dtype=float32)
Without GA:
Predictions :
[[0.9889404 0.00634338]
[0.03020517 0.9684899 ]
[0.28220823 0.76921546]
...
[0.08805525 0.92023355]
[0.9115724 0.08401334]
[0.15908712 0.8055146 ]]
With PyGAD GA:
Predictions :
[[0.4274468 0.47953305]
[0.40091008 0.38568377]
[0.3937818 0.41261795]
...
[0.3366004 0.43762493]
[0.43253532 0.4112898 ]
[0.40255183 0.4059006 ]]
经过 200 代之后,Fitness Score 保持不变,最终模型准确率低于 50%,这意味着它比随机猜测更差。我想我的模型权重根本没有被训练。当我使用二元交叉熵作为损失函数(也用于 GA 适应度函数)训练没有 ga 的相同 NN 模型时,它起作用了。我可以看到每个 epoch 的准确率都在上升,最终的 acc 都在 90% 以上;但是,当我尝试使用 PyGAD 库通过遗传算法训练模型时,它不起作用。是NN模型的问题还是我使用的适应度函数的问题?我已经尝试更改模型结构和一些可以在 PyGAD 库中使用的超参数,例如突变类型或父母交配的数量,但似乎没有什么对我有用。
编辑:我尝试创建 nn 模型,并在没有任何培训的情况下进行预测。然后我运行 ga_instance.run() 代码用 ga 训练模型(仍然,适应度根本没有上升),然后用那个应该训练的模型进行预测,有和没有 ga 训练的预测输出是一样的,这意味着在 ga 的过程中没有找到更好的预测。为什么会这样?
我打印了 ga 解决方案的每一代的适应度,我可以看到每一代都会产生不同的适应度分数(每一代的适应度分数都有非常小的改善),这意味着 ga 确实产生了不同的输出,但它们是只是比模型的初始重量差很多。即使经过许多代,也没有产生比初始重量更好的解决方案。这是否意味着我只需要更多的世代(比如成千上万的世代)来获得更好的解决方案?还是我选择的适应度函数有问题,使改进进度如此缓慢?
解决方案
您的模型有大量参数 (>6.1M)。只有嵌入层本身有 6M。对于这样的许多参数,预计遗传算法将花费大量时间来训练模型。这并不意味着你出了问题。我之前已经尝试过与一个巨大的 CNN 合作,并且取得了进展,但非常小。
根据您机器的能力,您应该尽可能增加解决方案的数量。也尽可能多地使用一代。
感谢您使用PyGAD!
推荐阅读
- html - 调整元素宽度的问题
- 和
- 和
- 和
- go - 扫掠 AABB 与 2D 线段
- angular - 如何在 ionic 5 中使用电容器应用程序实现谷歌标签管理器
- javascript - 如何使用 Javascript 更改/定义构建 CLI Node.js 工具的终端大小?
- r - 数据框到带有列名的文本文件
- c - 是否允许强制转换和取消引用“兼容”结构的结构指针?
- authentication - 如何将 Cisco AnyConnect 与 Freeradius 集成
- python - 在 tkinter 画布中绘制图像失败
- apache-beam - 使用 Apache Beam 计算过去 24 小时的移动平均线
- javascript - 如何从两个不同的数组中插入一个对象?