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。