引数の設定
python,pytorch初心者です。
pythonのコードで書かれたマルチエージェントシステムのプログラムをpytorch用に変更したのですがエラーが発生してしまいます。
引数に関することなのはわかるのですがどの_init__の引数を変更すればよいのかわかりません。
エラーメッセージ
TypeError: __init__() missing 1 required positional argument: 'params'
コード
pytorch
1class Walls: 2 def __init__(self, x0, y0, x1, y1): 3 self.x = [[x0, y0], [x1, y1]] 4 self.area = 0.0 5 6class Particles: 7 def __init__(self, dh, wall): 8 self.box = wall.get_box() 9 self.dh = dh 10 self.size = 0 11 self.area = 0 12 13class ParticleEnv: 14 def __init__(self, dh, wall): 15 self.par = Particles(dh, wall) 16 self.wall = wall 17 self.num_state = DEF_NUM_STATE 18 self.state_dim = DEF_STATE_DIM + 1 19 self.obs_size = self.num_state*self.state_dim 20 self.num_accel = DEF_NUM_ACCEL 21 self.num_dir = DEF_NUM_DIR 22 self.accel = [2.0, 1.0, 0.5] 23 self.dir_ang = np.zeros(self.num_dir) 24 for i in range(1,self.num_dir): 25 self.dir_ang[i] = DEF_DIR_ANG*i 26 self.num_action = self.num_dir * self.num_accel + 1 27 28
どの_init__の引数を変更すればよいのかわかりません。
質問にある情報からは、何を変更すれば良いかはわかりません。
しかし、書かれている三つのクラスの__init__ではないことは分かります。
ソースコードの全文とエラーコードの全文があれば、もう少しわかるかもしれません。
import torch
from torch import optim
import torch.nn.functional as F
import torch.nn as nn
import pfrl
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as pch
import matplotlib.patches
#matplotlib.use('Agg')
import math
import argparse
DEF_NUM_PAR = 2
DEF_DH = 0.5
DEF_H = 0.2
DEF_A = 4.0
DEF_DELTA = 0.0001
DEF_NUM_ACCEL = 3
DEF_NUM_DIR = 36
DEF_DIR_ANG = np.pi/18.0
DEF_NUM_STATE = 1
DEF_STATE_DIM = DEF_NUM_DIR
DEF_TOL_DENSE = 95.0
DEF_TOL_CONTACT = 0.03
class Walls:
def __init__(self, x0, y0, x1, y1):
self.x = [[x0, y0], [x1, y1]]
self.area = 0.0
def addPoint(self, x, y):
self.x.append([x, y])
def calc_area(self):
s = 0
n = len(self.x)
for i in range(n-1):
s += self.x[i][0]*self.x[i+1][1] - self.x[i+1][0]*self.x[i][1]
s += self.x[n-1][0]*self.x[0][1] - self.x[0][0]*self.x[n-1][1]
self.area = abs(s) * 0.5
def get_area(self):
return self.area
def get_box(self):
self.x_max, self.y_max = np.amax(self.x, axis=0)
self.x_min, self.y_min = np.amin(self.x, axis=0)
return [self.x_min, self.y_min, self.x_max, self.y_max]
def get_len(self):
return len(self.x)
# crossing number algorithm
def in_poly(self, x, y):
c = 0
size = len(self.x)
for i in range(size-1):
if (self.x[i][1]<=y and self.x[i+1][1]>y) or (self.x[i][1]>y and self.x[i+1][1]<=y):
v = (y - self.x[i][1]) / (self.x[i+1][1] - self.x[i][1])
if x < (self.x[i][0] + (v * (self.x[i+1][0] - self.x[i][0]))):
c = c + 1
if (self.x[size-1][1]<=y and self.x[0][1]>y) or (self.x[size-1][1]>y and self.x[0][1]<=y):
v = (y - self.x[size-1][1]) / (self.x[0][1] - self.x[size-1][1])
if x < (self.x[size-1][0] + (v * (self.x[0][0] - self.x[size-1][0]))):
c = c + 1
if c % 2 == 1:
return True
else:
return False
def draw(self):
return plt.Polygon(self.x,fill=False,linewidth=2)
class Particles:
def __init__(self, dh, wall):
self.box = wall.get_box()
self.dh = dh
self.size = 0
self.area = 0
def reset(self, wall, x, y):
self.x = []
if not x is None:
self.x.append([x,y])
#self.x.append([0.4,-0.65])
#self.x.append([0.4+DEF_H*2.0,-0.65])
#self.x.append([0.4+DEF_H*3.0,-0.65+math.sqrt(3.0)*DEF_H])
self.size = len(self.x)
self.v = [DEF_H*2.0 for i in range(self.size)]
def push_par(self, i, x, y):
self.x.insert(i,[x,y])
self.v.insert(i,DEF_H*2.0)
self.size = self.size + 1
def pop_par(self):
self.v.pop(0)
self.size = self.size - 1
return self.x.pop(0)
def step(self,i,theta,accel):
x = self.x[i][0]
y = self.x[i][1]
v = self.v[i] * accel
if v < DEF_TOL_CONTACT*0.5:
v = DEF_TOL_CONTACT*0.5
ux = np.cos(theta)
uy = np.sin(theta)
return [x+ux*v,y+uy*v,v]
def move(self,i,x,y,v):
self.x[i][0] = x
self.x[i][1] = y
self.v[i] = v
def calc_area(self):
self.area = self.size * np.pi * DEF_H * DEF_H
def get_area(self):
return self.area
def neighbor_search(self, i, x0, y0):
contact = 0
overlapp = False
for j in range(self.size):
if i != j:
x = self.x[j][0]
y = self.x[j][1]
r = np.sqrt((x0-x)*(x0-x)+(y0-y)*(y0-y))
if r < DEF_H*2.0+DEF_DELTA:
overlapp = True
break
if abs(DEF_H*2.0-r) < DEF_TOL_CONTACT:
contact += 1
return contact, overlapp
def draw(self,j,ax):
for i in range(0,j):
ax.add_patch(pch.Circle(xy=(self.x[i][0],self.x[i][1]),radius=DEF_H,fc="red",ec="k"))
for i in range(j,self.size):
ax.add_patch(pch.Circle(xy=(self.x[i][0],self.x[i][1]),radius=DEF_H,fc="blue",ec="k"))
#ax.add_patch(pch.Circle(xy=(self.x[j][0],self.x[j][1]),radius=DEF_H,fc="red",ec="k"))
class ParticleEnv:
def __init__(self, dh, wall):
self.par = Particles(dh, wall)
self.wall = wall
self.num_state = DEF_NUM_STATE
self.state_dim = DEF_STATE_DIM + 1
self.obs_size = self.num_state*self.state_dim
self.num_accel = DEF_NUM_ACCEL
self.num_dir = DEF_NUM_DIR
self.accel = [2.0, 1.0, 0.5]
self.dir_ang = np.zeros(self.num_dir)
for i in range(1,self.num_dir):
self.dir_ang[i] = DEF_DIR_ANG*i
self.num_action = self.num_dir * self.num_accel + 1
def reset(self, x=None, y=None):
self.par.reset(self.wall, x, y)
self.calc_states()
return self.get_obs()
def calc_vec2d_ang(self, x, y):
dx = np.linalg.norm(x)
dy = np.linalg.norm(y)
r = np.dot(x,y)
return np.arccos(r/(dx*dy))
def calc_state(self, id):
state = np.zeros(self.state_dim).astype(np.float32)
xo = self.par.x[id][0]
yo = self.par.x[id][1]
# distance from other particles
for i in range(self.num_dir):
state[i] = DEF_H*DEF_A*2.0
pList = []
for i in range(self.par.size):
if id != i:
x = self.par.x[i][0]
y = self.par.x[i][1]
r = np.sqrt((x-xo)*(x-xo)+(y-yo)*(y-yo))
if r <= DEF_H*DEF_A:
pList.append([i,np.absolute(r-DEF_H*2.0)])
for j in range(len(pList)):
i = pList[j][0]
r = pList[j][1]
x = self.par.x[i][0]
y = self.par.x[i][1]
t = self.calc_vec2d_ang(np.array([x-xo,y-yo]),
np.array([1.0,0.0]))
s = (1.0-xo)*(y-yo)-(0.0-yo)*(x-xo)
idx = int(t/DEF_DIR_ANG)
if s > 0.0:
if state[idx] > r:
state[idx] = r
else:
if state[self.num_dir-idx-1] > r:
state[self.num_dir-idx-1] = r
# distance from wall
for i in range(self.num_dir):
if state[i] > DEF_H*DEF_A:
theta = self.dir_ang[i]
dx = np.cos(theta)
dy = np.sin(theta)
dx = xo + dx*self.par.v[id]*2.0
dy = yo + dy*self.par.v[id]*2.0
inpoly = self.wall.in_poly(dx,dy)
if not inpoly:
state[i] = -1.0
else:
state[i] = -0.01
for i in range(self.num_dir):
if state[i] > 0.0:
state[i] = 1.0-state[i]/(DEF_H*DEF_A)
state[self.state_dim-1] = self.par.v[id]
return state
def calc_states(self):
self.state = []
for i in range(self.par.size):
self.state.append(self.calc_state(i))
return self.get_obs()
def get_obs(self):
return self.state
def get_obs_i(self,i):
return self.state[i]
def random_action(self):
act = np.random.randint(0,self.num_action-1)
return act
def step(self, i, act):
obs = self.state
reward = 0
done = False
if act == 0:
x,y,v = self.par.step(i,0,0)
v = 0.0
else:
accel = self.accel[(act-1) % DEF_NUM_ACCEL]
theta = self.dir_ang[int((act-1) % DEF_NUM_DIR)]
x,y,v = self.par.step(i,theta,accel)
inpoly = self.wall.in_poly(x,y)
if not inpoly:
reward = -2
else:
contact, overlapp = self.par.neighbor_search(i,x,y)
if overlapp:
reward = -0.1
else:
self.par.move(i,x,y,v)
self.state = self.calc_state(i)
if contact > 2:
reward = contact*contact*10
done = True
elif contact > 0:
reward = contact*contact
else:
reward = -1
obs = self.state
return obs, reward, done
def render(self,n):
plt.cla()
ax = plt.axes()
ax.add_patch(self.wall.draw())
self.par.draw(n,ax)
plt.xlim(-2,2)
plt.ylim(-1.5,2)
plt.pause(.01)
#fname = "img_se_ddqn_sample_{0:06}_{1:06}.png".format(i,j)
#plt.savefig(fname)
def train_ddqn(env,agents,n_epoch,n_epi,max_elen,data):
for ep in range(n_epoch):
#np.random.shuffle(data)
for e in range(n_epi):
env.reset()
for p in range(DEF_NUM_PAR):
env.par.push_par(p,data[e*DEF_NUM_PAR+p][0],data[e*DEF_NUM_PAR+p][1])
R = 0
t = 0
done = True
rewards = [0.0 for p in range(DEF_NUM_PAR)]
while t < max_elen:
obs = env.calc_states()
for p in range(DEF_NUM_PAR):
act = agents[p].act_and_train(obs[p], rewards[p])
ob, reward, did = env.step(p, act)
rewards[p] += reward
if not did:
done = False
t += 1
if ep%50 == 0 and e == n_epi-1:
env.render(DEF_NUM_PAR)
R = sum(rewards) / DEF_NUM_PAR
print('train_epoch: %d train_episode: %d num_step: %d ave_reward: %d done: %d' % (ep,e,t,R,done))
for p in range(DEF_NUM_PAR):
agents[p].stop_episode_and_train(obs[p], rewards[p], done)
def test_ddqn(env,agent,n_epoch,n_epi,max_elen,data):
for ep in range(n_epoch):
for e in range(n_epi):
obs = env.reset(data[e][0],data[e][1])
R = 0
t = 0
done = False
reward = 0
while t < max_elen:
act = agent.act(obs)
obs, reward, done = env.step(0, act)
R += reward
t += 1
#env.render(0)
print('test_epoch: %d test_episode: %d num_step: %d reward: %d done: %d' % (ep,e,t,R,done))
agent.stop_episode()
def agent_setup(args, env):
# Q functions
q_func = pfrl.q_functions.FCStateQFunctionWithDiscreteAction(
env.obs_size, env.num_action,
n_hidden_channels=args.n_hidden_channels,
n_hidden_layers=args.n_hidden_layers)
# Optimizer
optimizer = torch.optim.Adam(eps=1.0e-2)
optimizer.setup(q_func)
# Explorer
explorer = pfrl.explorers.ConstantEpsilonGreedy(
epsilon=args.end_epsilon, random_action_func=env.random_action)
#explorer = chainerrl.explorers.LinearDecayEpsilonGreedy(
# args.start_epsilon, args.end_epsilon, args.final_exploration_steps,
# random_action_func=env.random_action)
# Replay buffer
replay_buffer = pfrl.replay_buffer.ReplayBuffer(capacity=10000)
def phi(obs):
return obs.astype(np.float32)
agent = pfrl.agents.DoubleDQN(
q_func, optimizer, replay_buffer,
gamma=args.gamma, explorer=explorer,
replay_start_size=args.replay_start_size,
update_interval=args.update_interval,
target_update_method=args.target_update_method,
target_update_interval=args.target_update_interval,
soft_update_tau=args.soft_update_tau,
phi=phi)
return agent
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--start-epsilon",type=float,default=0.9)
parser.add_argument("--end-epsilon",type=float,default=0.1)
parser.add_argument("--final-exploration-steps",type=int,default=10000)
parser.add_argument("--noisy-net-sigma",type=float,default=None)
parser.add_argument("--n-train-epochs",type=int,default=100)
parser.add_argument("--n-train-episodes",type=int,default=100)
parser.add_argument("--n-test-epochs",type=int,default=1)
parser.add_argument("--n-test-episodes",type=int,default=20)
parser.add_argument("--max-episode-len",type=int,default=50)
parser.add_argument("--replay-start-size",type=int,default=32)
parser.add_argument("--target-update-method",type=str,default="hard")
parser.add_argument("--target-update-interval",type=int,default=320)
parser.add_argument("--update-interval",type=int,default=1)
parser.add_argument("--soft-update-tau",type=float,default=0.01)
parser.add_argument("--n-hidden-channels",type=int,default=97)
parser.add_argument("--n-hidden-layers",type=int,default=3)
parser.add_argument("--gamma",type=float,default=0.9)
parser.add_argument("--train",action="store_true",default=True)
parser.add_argument("--test",action="store_true",default=True)
parser.add_argument("--run",action="store_true")
args = parser.parse_args(args=[])
# Wall boundaries
wall = Walls(-1.5, -0.866, 1.5, -0.866)
wall.addPoint(0.0, 0.866*2.0)
wall.calc_area()
wall.get_box()
env = ParticleEnv(DEF_DH, wall)
obs = env.reset()
# Train and Test data
np.random.seed(seed=9998878)
train_data = []
for i in range(args.n_train_episodes):
for j in range(DEF_NUM_PAR):
while True:
x = np.random.uniform(wall.x_min, wall.x_max, 1)
y = np.random.uniform(wall.y_min, wall.y_max, 1)
if wall.in_poly(x,y):
contact, overlapp = env.par.neighbor_search(-1,x,y)
if not overlapp:
env.par.push_par(j,x[0],y[0])
break
for j in range(DEF_NUM_PAR):
train_data.append(env.par.pop_par())
agents = []
for i in range(DEF_NUM_PAR):
agent = agent_setup(args, env)
agents.append(agent)
if args.train:
train_ddqn(env, agents, args.n_train_epochs, args.n_train_episodes,
args.max_episode_len, train_data)
if args.test:
test_ddqn(env, agents, args.n_test_epochs, args.n_test_episodes,
args.max_episode_len, test_data)
if __name__ == '__main__':
main()
TypeError Traceback (most recent call last)
<ipython-input-2-eb4a33b9d911> in <module>
428
429 if __name__ == '__main__':
--> 430 main()
<ipython-input-2-eb4a33b9d911> in main()
415 agents = []
416 for i in range(DEF_NUM_PAR):
--> 417 agent = agent_setup(args, env)
418 agents.append(agent)
419
<ipython-input-2-eb4a33b9d911> in agent_setup(args, env)
336
337 # Optimizer
--> 338 optimizer = torch.optim.Adam(eps=1.0e-2)
339 optimizer.setup(q_func)
340
TypeError: __init__() missing 1 required positional argument: 'params'
以上がソースコードと発生したエラーです。
とても量が多いのですがよろしくお願いします。
ちなみにjupyter上で実行しました
回答1件
あなたの回答
tips
プレビュー