Keras 的可变输入和输出大小
Variable input and output size for Keras
在开始之前,我对 Keras 和机器学习还很陌生。我很了解这个理论,但语法不太了解。
我正在尝试使用 Keras 创建强化学习神经网络。要解决的问题本质上是旅行商问题。问题是,网络是根据其位置和环境进行馈送的,这是一个随机创建的点网络,例如 [[0,5]、[30,17]、[19,83]... 和当代理通过该网络时,它会随着无法再次访问的点而发生变化。因此,如果代理从 [0,0] 变为 [0,5] 然后变为 [30,17],输入将看起来像 [0,5]、[30,17]、[19,83] 到 [30, 17]、[19,83] 至 [19,83]。输出也有类似的问题,它只是可能移动到的位置的索引。这意味着可以有任意数量的输出。
输入的大小最初是 100,输出也可以是 0 到 100 之间的任何值。像用数字填充输入这样的方法是行不通的,因为网络会被馈送到一个无法到达的位置,并且用数字填充输出存在类似的问题 - 网络可以在 'moving'([0,0] 到 [0,0] 等)时保持相同的位置。智能体的时间也是有限的,因此即使填充了随机数,它也只能前往实际不存在的位置,这并不能解决手头的问题。
如何动态更改输入和输出大小?甚至可以,如果不可以,应该怎么做?
编辑:代码,因为有人想要它。相当难以理解,但本质上是一个class,包含可以完成的动作,self.state形式的输入,以及self.point_space形式的环境。奖励计算为每一步行进的距离,完成后,该距离与随机循环相比。更重要的是我是否可以更改输入和输出大小。
class GraphEnv(Env):
def __init__(self):
self.point_space = createpoints()
self.action_space = Discrete(len(self.point_space))
self.observation_space = self.point_space.copy()
self.state = [[0,0]]
for i in self.observation_space:
self.state.append(i)
self.length = len(self.point_space)
self.totallen = 0
self.unchangedpoint_space = self.point_space.copy()
def step(self, action):
oldstate = self.state[0]
self.state = []
self.state.append(list(self.point_space[action-1]))
try:
del self.point_space[action-1]
except:
pass
self.observation_space = self.point_space.copy()
for i in self.observation_space:
self.state.append(i)
self.action_space = Discrete(len(self.point_space))
#print("self.state = ", self.state)
reward = int(-math.sqrt((oldstate[0] - self.state[0][0])**2 + (oldstate[1] - self.state[0][1])**2))
self.totallen += reward
self.length -= 1
if self.length <= 0:
#print("unchanged =", self.unchangedpoint_space)
randomscore = scoreforrandom(self.unchangedpoint_space)
reward = self.totallen - randomscore
#print("totallen =",self.totallen)
#print("randomscore =", randomscore)
#print("reward", reward)
done = True
else:
done = False
info = {}
return(self.state,reward,done,info)
def render(self):
pass
def reset(self):
self.state = [[0,0]]
self.length = 100
self.point_space = createpoints()
self.observation_space = self.point_space.copy()
self.state.append(self.observation_space)
self.unchangedpoint_space = self.point_space.copy()
#print("unchanged on init", self.unchangedpoint_space)
self.action_space = Discrete(len(self.point_space))
self.totallen = 0
pass
我用作帮助的视频:https://www.youtube.com/watch?v=bD6V3rcr_54&t=77s&ab_channel=NicholasRenotte
找到解决方案 - 为了修复不断变化的输出,我改为使用 4 个动作 - 上下左右。这也有助于解决不断变化的输入,现在可以选择填充 9999。
在开始之前,我对 Keras 和机器学习还很陌生。我很了解这个理论,但语法不太了解。
我正在尝试使用 Keras 创建强化学习神经网络。要解决的问题本质上是旅行商问题。问题是,网络是根据其位置和环境进行馈送的,这是一个随机创建的点网络,例如 [[0,5]、[30,17]、[19,83]... 和当代理通过该网络时,它会随着无法再次访问的点而发生变化。因此,如果代理从 [0,0] 变为 [0,5] 然后变为 [30,17],输入将看起来像 [0,5]、[30,17]、[19,83] 到 [30, 17]、[19,83] 至 [19,83]。输出也有类似的问题,它只是可能移动到的位置的索引。这意味着可以有任意数量的输出。
输入的大小最初是 100,输出也可以是 0 到 100 之间的任何值。像用数字填充输入这样的方法是行不通的,因为网络会被馈送到一个无法到达的位置,并且用数字填充输出存在类似的问题 - 网络可以在 'moving'([0,0] 到 [0,0] 等)时保持相同的位置。智能体的时间也是有限的,因此即使填充了随机数,它也只能前往实际不存在的位置,这并不能解决手头的问题。
如何动态更改输入和输出大小?甚至可以,如果不可以,应该怎么做?
编辑:代码,因为有人想要它。相当难以理解,但本质上是一个class,包含可以完成的动作,self.state形式的输入,以及self.point_space形式的环境。奖励计算为每一步行进的距离,完成后,该距离与随机循环相比。更重要的是我是否可以更改输入和输出大小。
class GraphEnv(Env):
def __init__(self):
self.point_space = createpoints()
self.action_space = Discrete(len(self.point_space))
self.observation_space = self.point_space.copy()
self.state = [[0,0]]
for i in self.observation_space:
self.state.append(i)
self.length = len(self.point_space)
self.totallen = 0
self.unchangedpoint_space = self.point_space.copy()
def step(self, action):
oldstate = self.state[0]
self.state = []
self.state.append(list(self.point_space[action-1]))
try:
del self.point_space[action-1]
except:
pass
self.observation_space = self.point_space.copy()
for i in self.observation_space:
self.state.append(i)
self.action_space = Discrete(len(self.point_space))
#print("self.state = ", self.state)
reward = int(-math.sqrt((oldstate[0] - self.state[0][0])**2 + (oldstate[1] - self.state[0][1])**2))
self.totallen += reward
self.length -= 1
if self.length <= 0:
#print("unchanged =", self.unchangedpoint_space)
randomscore = scoreforrandom(self.unchangedpoint_space)
reward = self.totallen - randomscore
#print("totallen =",self.totallen)
#print("randomscore =", randomscore)
#print("reward", reward)
done = True
else:
done = False
info = {}
return(self.state,reward,done,info)
def render(self):
pass
def reset(self):
self.state = [[0,0]]
self.length = 100
self.point_space = createpoints()
self.observation_space = self.point_space.copy()
self.state.append(self.observation_space)
self.unchangedpoint_space = self.point_space.copy()
#print("unchanged on init", self.unchangedpoint_space)
self.action_space = Discrete(len(self.point_space))
self.totallen = 0
pass
我用作帮助的视频:https://www.youtube.com/watch?v=bD6V3rcr_54&t=77s&ab_channel=NicholasRenotte
找到解决方案 - 为了修复不断变化的输出,我改为使用 4 个动作 - 上下左右。这也有助于解决不断变化的输入,现在可以选择填充 9999。