囚徒5.3_SSA_BP算法

麻雀算法加上bp网络


import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense
from sklearn.metrics import accuracy_score

# 加载MNIST数据集
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0
X_test = X_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

# 定义CNN模型
def create_model(weights=None):
    inputs = Input(shape=(28, 28, 1))
    x = Conv2D(32, kernel_size=(3, 3), activation='relu')(inputs)
    x = MaxPooling2D(pool_size=(2, 2))(x)
    x = Flatten()(x)
    x = Dense(128, activation='relu')(x)
    outputs = Dense(10, activation='softmax')(x)
    model = Model(inputs, outputs)
    if weights is not None:
        model.set_weights(weights)
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    return model

# 定义麻雀算法参数
class SSA:
    def __init__(self, pop_size, dim, max_iter, lb, ub):
        self.pop_size = pop_size
        self.dim = dim
        self.max_iter = max_iter
        self.lb = lb
        self.ub = ub
        self.X = np.random.uniform(low=lb, high=ub, size=(pop_size, dim))
        self.p_fit = np.full(pop_size, float('inf'))
        self.g_best = None
        self.g_best_fit = float('inf')

    def fitness(self, x):
        # 将个体解转换为CNN权重
        weights = self.decode_weights(x)
        model = create_model(weights)
        model.fit(X_train, y_train, epochs=1, batch_size=32, verbose=0)
        y_pred = model.predict(X_test)
        return -accuracy_score(np.argmax(y_test, axis=1), np.argmax(y_pred, axis=1))

    def decode_weights(self, x):
        # 解码权重,这里假设dim与CNN权重的总数匹配
        model = create_model()
        shapes = [w.shape for w in model.get_weights()]
        weights = []
        idx = 0
        for shape in shapes:
            size = np.prod(shape)
            weights.append(x[idx:idx + size].reshape(shape))
            idx += size
        return weights

    def update(self):
        for t in range(self.max_iter):
            for i in range(self.pop_size):
                fit = self.fitness(self.X[i])
                if fit < self.p_fit[i]:
                    self.p_fit[i] = fit
                    if fit < self.g_best_fit:
                        self.g_best = self.X[i].copy()
                        self.g_best_fit = fit
            for i in range(self.pop_size):
                r1 = np.random.rand()
                r2 = np.random.rand()
                if r2 < 0.8:
                    self.X[i] = self.X[i] + r1 * (self.g_best - self.X[i])
                else:
                    self.X[i] = self.X[i] + r1 * (self.X[i] - self.g_best)
                self.X[i] = np.clip(self.X[i], self.lb, self.ub)

# 初始化麻雀算法
num_weights = sum([np.prod(w.shape) for w in create_model().get_weights()])
ssa = SSA(pop_size=10, dim=num_weights, max_iter=10, lb=-1, ub=1)
ssa.update()

# 输出最优解并评估
optimal_weights = ssa.decode_weights(ssa.g_best)
model = create_model(optimal_weights)
model.fit(X_train, y_train, epochs=5, batch_size=32, verbose=1)
loss, accuracy = model.evaluate(X_test, y_test, verbose=0)
print("Test accuracy:", accuracy)

posted @ 2024-06-02 15:39  玩意  阅读(16)  评论(0)    收藏  举报