You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GlobalBestPSO训练神经网络时出现维度重塑ValueError的问题求助

GlobalBestPSO训练神经网络时出现维度重塑ValueError的问题求助

兄弟我懂你这头疼的问题!我之前也踩过PySwarms这个参数传递的坑,咱们一步步来拆解:

错误原因分析

你看到的560其实是这么来的:你设置了n_particles=10,每个粒子对应56个神经网络参数,PySwarms会把这10个粒子的参数堆叠成一个二维数组传给optimize_nn函数,总长度就是10×56=560。而你现在的函数直接把整个560长度的数组拿去reshape成(4,8),自然就会报维度不匹配的错误!

解决方案:修改目标函数以处理批量粒子参数

PySwarms的目标函数要求返回每个粒子对应的损失值,所以我们需要遍历每个粒子的参数,分别计算其对应的1-accuracy,最后返回一个长度等于粒子数的数组。

下面是修改后的完整代码,重点标注了修改的部分:

import numpy as np
import pyswarms as ps
import tensorflow as tf
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# Load Iris dataset
iris = load_iris()
X = iris.data
y = iris.target

# Normalize input data
X = X.astype('float32') / np.max(X)

# One-hot encode target labels
y = tf.keras.utils.to_categorical(y)

# Split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.80, random_state=11)

# Define bounds for the particles in PSO
param_bounds = ([-1] * 56, [1] * 56)  # 56 parameters for the weights

# 修改后的目标函数:处理批量粒子参数
def optimize_nn(params):
    # params是形状为(n_particles, dimensions)的二维数组
    n_particles = params.shape[0]
    losses = []
    
    for i in range(n_particles):
        single_params = params[i]  # 取出单个粒子的56维参数
        
        model = Sequential()
        model.add(Dense(8, input_shape=(4,), activation='relu'))
        model.add(Dense(3, activation='sigmoid'))
        model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

        # Set the weights for each layer separately
        first_layer_weights = single_params[:32].reshape((4, 8))
        second_layer_weights = single_params[32:].reshape((8, 3))
        model.layers[0].set_weights([first_layer_weights, np.zeros(8)])
        model.layers[1].set_weights([second_layer_weights, np.zeros(3)])

        _, accuracy = model.evaluate(X_train, y_train, verbose=0)
        losses.append(1 - accuracy)  # 收集每个粒子的损失值
    
    return np.array(losses)  # 返回所有粒子的损失数组

# Create a PSO optimizer
optimizer = ps.single.GlobalBestPSO(n_particles=10, dimensions=56, options={'c1': 0.5, 'c2': 0.3, 'w': 0.9})

# Perform optimization
best_cost, best_params = optimizer.optimize(optimize_nn, iters=50)

# Create a new neural network model
best_model = Sequential()
best_model.add(Dense(8, input_shape=(4,), activation='relu'))
best_model.add(Dense(3, activation='sigmoid'))

# Set the best weights found by PSO
first_layer_weights = best_params[:32].reshape((4, 8))
second_layer_weights = best_params[32:].reshape((8, 3))
best_model.layers[0].set_weights([first_layer_weights, np.zeros(8)])
best_model.layers[1].set_weights([second_layer_weights, np.zeros(3)])

# Compile the best model
best_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Evaluate the best model on the test set
loss, accuracy = best_model.evaluate(X_test, y_test, verbose=0)
print("Test set accuracy: {:.2f}%".format(accuracy * 100))

关于官方示例的问题

你提到官方示例也有同样问题,大概率是因为PySwarms的版本更新导致API变化——旧版本可能是向目标函数传递单个粒子的参数,而新版本默认传递所有粒子的参数矩阵。按照上面的修改方式调整官方示例的目标函数,就能解决问题啦。

备注:内容来源于stack exchange,提问作者Abdallah Abu Samaha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:58:09