mirror of
https://github.com/jung-geun/PSO.git
synced 2025-12-20 04:50:45 +09:00
EBPSO 알고리즘 구현 - 선택지로 추가 random 으로 분산시키는 방법 구현 - 선택지로 추가 iris 기준 98퍼센트로 나오나 정확한 결과를 지켜봐야 할것으로 보임
67 lines
2.3 KiB
Python
Executable File
67 lines
2.3 KiB
Python
Executable File
import random
|
|
|
|
import numpy as np
|
|
|
|
from psokeras.optimizer import BIG_SCORE
|
|
|
|
|
|
class Particle:
|
|
def __init__(self, model, params):
|
|
self.model = model
|
|
self.params = params
|
|
self.init_weights = model.get_weights()
|
|
self.velocities = [None] * len(self.init_weights)
|
|
self.length = len(self.init_weights)
|
|
for i, layer in enumerate(self.init_weights):
|
|
self.velocities[i] = np.random.rand(*layer.shape) / 5 - 0.10
|
|
# self.velocities[i] = np.zeros(layer.shape)
|
|
|
|
self.best_weights = None
|
|
self.best_score = BIG_SCORE
|
|
|
|
def get_score(self, x, y, update=True):
|
|
local_score = self.model.evaluate(x, y, verbose=0)
|
|
if local_score < self.best_score and update:
|
|
self.best_score = local_score
|
|
self.best_weights = self.model.get_weights()
|
|
|
|
return local_score
|
|
|
|
def _update_velocities(self, global_best_weights, depth):
|
|
new_velocities = [None] * len(self.init_weights)
|
|
weights = self.model.get_weights()
|
|
local_rand, global_rand = random.random(), random.random()
|
|
|
|
for i, layer in enumerate(weights):
|
|
if i >= depth:
|
|
new_velocities[i] = self.velocities[i]
|
|
continue
|
|
new_v = self.params['acc'] * self.velocities[i]
|
|
new_v = new_v + self.params['local_acc'] * local_rand * (self.best_weights[i] - layer)
|
|
new_v = new_v + self.params['global_acc'] * global_rand * (global_best_weights[i] - layer)
|
|
new_velocities[i] = new_v
|
|
|
|
self.velocities = new_velocities
|
|
|
|
def _update_weights(self, depth):
|
|
old_weights = self.model.get_weights()
|
|
new_weights = [None] * len(old_weights)
|
|
for i, layer in enumerate(old_weights):
|
|
if i>= depth:
|
|
new_weights[i] = layer
|
|
continue
|
|
new_w = layer + self.velocities[i]
|
|
new_weights[i] = new_w
|
|
|
|
self.model.set_weights(new_weights)
|
|
|
|
def step(self, x, y, global_best_weights,depth=None):
|
|
if depth is None:
|
|
depth = self.length
|
|
self._update_velocities(global_best_weights, depth)
|
|
self._update_weights(depth)
|
|
return self.get_score(x, y)
|
|
|
|
def get_best_weights(self):
|
|
return self.best_weights
|