未在 PyGAD 中训练的二元分类 NN 模型权重
Binary Classification NN Model Weights not being Trained in PyGAD
这是我正在编写的代码:
Fake News Detection Google Colab Notebook
我使用的数据集:
fake_or_real_news
手套嵌入层:
glove.twitter.27B.200d
我一直在试用 PyGAD,这是一个 python 用于机器学习的遗传算法库。
我想实现的是假新闻检测。我所做的是对文章进行预处理,然后将它们 t运行sform 成向量。我使用 Glove 作为 NN 中的嵌入层。我尝试在没有 GA 的情况下使用 NN 模型进行训练,并且效果很好。然后我按照教程 How To Train Keras Models Using the Genetic Algorithm with PyGAD 将 NN 应用于 PyGAD GA,过程似乎 运行 很好,但适应度得分甚至在 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%,这意味着它比 运行dom 猜测还差。我想我的模型权重根本没有经过训练。当我使用二元交叉熵作为损失函数(也用于 GA 适应度函数)在没有 ga 的情况下训练相同的 NN 模型时,它起作用了。我可以看到每个 epoch 的准确率都在上升,最终的准确率在 90% 以上;但是,当我尝试使用 PyGAD 库通过遗传算法训练模型时,它不起作用。问题出在 NN 模型上还是我使用的适应度函数上?我已经尝试更改模型结构和一些我可以在 PyGAD 库中使用的超参数,例如突变类型或 parents 交配的数量,但似乎对我没有任何作用。
编辑:我尝试创建 nn 模型,并在没有任何训练的情况下进行预测。然后我 运行 ga_instance.run() 代码用 ga 训练模型(仍然,适应度根本没有上升),然后用那个应该训练过的模型进行预测,预测输出有和没有ga training 都是一样的,也就是说在ga的过程中没有发现更好的预测。为什么会这样?
我打印了每一代 ga 解决方案的适应度,我可以看到每一代都产生了不同的适应度分数集(每一代的适应度分数都有很小的提高),这意味着 ga 确实产生了不同的输出,但它们只是比模型的初始权重差很多。即使经过许多代,也没有产生比初始权重更好的解决方案。这是否意味着我只需要更多的世代(比如数千代)来获得更好的解决方案?还是我选择的适应度函数有问题导致提升的速度这么慢?
您的模型有大量参数(>610 万)。只有嵌入层本身有 6M。对于许多这样的参数,遗传算法预计会花费很多时间来训练模型。这并不意味着你制造了问题。我之前已经尝试过与一个巨大的 CNN 合作,并且取得了进展但非常小。
根据自己机器的能力,尽量增加解的数量。也尽可能使用多代。
感谢使用PyGAD!
这是我正在编写的代码: Fake News Detection Google Colab Notebook
我使用的数据集: fake_or_real_news
手套嵌入层: glove.twitter.27B.200d
我一直在试用 PyGAD,这是一个 python 用于机器学习的遗传算法库。
我想实现的是假新闻检测。我所做的是对文章进行预处理,然后将它们 t运行sform 成向量。我使用 Glove 作为 NN 中的嵌入层。我尝试在没有 GA 的情况下使用 NN 模型进行训练,并且效果很好。然后我按照教程 How To Train Keras Models Using the Genetic Algorithm with PyGAD 将 NN 应用于 PyGAD GA,过程似乎 运行 很好,但适应度得分甚至在 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%,这意味着它比 运行dom 猜测还差。我想我的模型权重根本没有经过训练。当我使用二元交叉熵作为损失函数(也用于 GA 适应度函数)在没有 ga 的情况下训练相同的 NN 模型时,它起作用了。我可以看到每个 epoch 的准确率都在上升,最终的准确率在 90% 以上;但是,当我尝试使用 PyGAD 库通过遗传算法训练模型时,它不起作用。问题出在 NN 模型上还是我使用的适应度函数上?我已经尝试更改模型结构和一些我可以在 PyGAD 库中使用的超参数,例如突变类型或 parents 交配的数量,但似乎对我没有任何作用。
编辑:我尝试创建 nn 模型,并在没有任何训练的情况下进行预测。然后我 运行 ga_instance.run() 代码用 ga 训练模型(仍然,适应度根本没有上升),然后用那个应该训练过的模型进行预测,预测输出有和没有ga training 都是一样的,也就是说在ga的过程中没有发现更好的预测。为什么会这样?
我打印了每一代 ga 解决方案的适应度,我可以看到每一代都产生了不同的适应度分数集(每一代的适应度分数都有很小的提高),这意味着 ga 确实产生了不同的输出,但它们只是比模型的初始权重差很多。即使经过许多代,也没有产生比初始权重更好的解决方案。这是否意味着我只需要更多的世代(比如数千代)来获得更好的解决方案?还是我选择的适应度函数有问题导致提升的速度这么慢?
您的模型有大量参数(>610 万)。只有嵌入层本身有 6M。对于许多这样的参数,遗传算法预计会花费很多时间来训练模型。这并不意味着你制造了问题。我之前已经尝试过与一个巨大的 CNN 合作,并且取得了进展但非常小。
根据自己机器的能力,尽量增加解的数量。也尽可能使用多代。
感谢使用PyGAD!