Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발이 취미인 개발자

AttributeError: module 'tensorflow._api.v2.train' has no attribute 'GradientDescentOptimizer' 오류 본문

딥러닝 & 머신러닝

AttributeError: module 'tensorflow._api.v2.train' has no attribute 'GradientDescentOptimizer' 오류

도그풋79 2022. 7. 24. 11:46

딥러닝 강의가 2017년 버전이라  예제로 나온 소스코드가 너무 오래 되서 동작이 되질 않았다.

tensorflow 1.0 버전에 작성된 코드라 2.0에서는 동작을 하지 않는다.

구글링을 해보니 tf.compat.v1.disabled_v2_behavior()를 상단에 추가해 주면 1.0 코드도 2.0에서 가능하다고 하는데

그럼에도 불구하기 실행은 되지 않았다.

 

아래 소스가 실행되지 않는 tensorflow 1.0 버전의 소스이다.

import gym
import numpy as np
import tensorflow as tf
from gym.envs.registration import register

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={'map_name' : '4x4', 'is_slippery': True}
)

env = gym.make("FrozenLake-v3")

input_size = env.observation_space.n
output_size = env.action_space.n
learning_rate = 0.1

def loss(Y, Qpred):
    return tf.reduce_sum(tf.square(Y - Qpred))

def one_hot(x):
    return np.identity(16)[x:x + 1]

# tensorflow 1.0
X = tf.Variable(tf.ones(shape=[1, input_size]), dtype=tf.float32)
W = tf.Variable(tf.random.uniform([input_size, output_size], 0, 0.01))
Qpred = tf.matmul(X, W)
Y = tf.Variable(tf.ones(shape=[1, output_size]), dtype=tf.float32)

dis = .99
num_episodes = 1000
rList = []

# tensorflow 1.0
init = tf.global_variables_initializer()
with tf.Session() as sess:
     sess.run(init)
    for i in range(num_episodes):
        s = env.reset()
        e = 1. / ((i / 50) + 10)
        rAll = 0
        done = False
        local_loss = []
        while not done:
            Qs = sess.run(Qpred, feed_dict={X: one_hot(s)})
            if np.random.rand(1) < e:
                a = env.action_space.sample()
            else:
                a = np.argmax(Qs)
            s1, reward, done, _ = env.step(a)
            if done:
                Qs[0, a] = reward
            else:
                #Qs1 = sess.run(Qpred, feed_dict={X: one_hot(s1)})
                Qs[0, a] = reward + dis * np.max(Qs1)

            sess.run(train, feed_dict={X: one_hot(s), Y:Qs})
            rAll += reward
            s = s1

        rList.append(rAll)

print("Percent of successful episodes :" + str(sum(rList) / num_episodes) + "%")

해결 방법은 두가지가 있는 하나는 아예 2.0 소스코드 변경하는 방법과 tf.compat.v1을 이용한 방법이 있다.

우선 tf.compat.v1을 활용하면 아래 소스를 차례대로 수정해 주면 된다.

 

해결방법 1.

 

(수정 전)

train = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss) 

 

(수정 후)

train = tf.compat.v1.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)


(수정 전)

init = tf.global_variables_initializer()
with tf.Session() as sess:

 

(수정 후)

init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:


마지막으로 아래와 같이 소스코드 도입부에 tf 2.0 명령어를 실행 중지하는 명령어를 추가해 준다.

 

import gym
import numpy as np
import tensorflow as tf
from gym.envs.registration import register

tf.compat.v1.disable_v2_behavior() #tf 2.0 실행을 중지, tf 1.0 코드만 실행되도록 처리

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={'map_name' : '4x4', 'is_slippery': True}
)

 

해결방법 2.

이거는 아예 소스코드를 2.0 버전으로 모두 바꾸는 방법이다. 수정된 전체 코드는 다음과 같다.

import gym
import numpy as np
import tensorflow as tf
from gym.envs.registration import register

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={'map_name' : '4x4', 'is_slippery': True}
)

env = gym.make("FrozenLake-v3")

input_size = env.observation_space.n
output_size = env.action_space.n
learning_rate = 0.1

def loss(Y, Qpred):
    return tf.reduce_sum(tf.square(Y - Qpred))

def one_hot(x):
    return np.identity(16)[x:x + 1]

# tensorflow 1.0
# X = tf.Variable(tf.ones(shape=[1, input_size]), dtype=tf.float32)
# W = tf.Variable(tf.random.uniform([input_size, output_size], 0, 0.01))
# Qpred = tf.matmul(X, W)
# Y = tf.Variable(tf.ones(shape=[1, output_size]), dtype=tf.float32)
# train = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)

# tensorflow 2.0
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(env.action_space.n, input_shape=(None, env.observation_space.n)))
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.1)
            , loss=loss
            , metrics=['accuracy'])
dis = .99
num_episodes = 1000
rList = []

# tensorflow 1.0
# init = tf.global_variables_initializer()
# with tf.Session() as sess:
#     sess.run(init)
for i in range(num_episodes):
    s = env.reset()
    e = 1. / ((i / 50) + 10)
    rAll = 0
    done = False
    local_loss = []
    while not done:
        #Qs = sess.run(Qpred, feed_dict={X: one_hot(s)}) - tensorflow 1.0
        Qs = model.predict(one_hot(s)) # tensorflw 2.0

        if np.random.rand(1) < e:
            a = env.action_space.sample()
        else:
            a = np.argmax(Qs)
        s1, reward, done, _ = env.step(a)
        if done:
            Qs[0, a] = reward
        else:
            #Qs1 = sess.run(Qpred, feed_dict={X: one_hot(s1)}) # tensorflw 1.0
            Qs1 = model.predict(one_hot(s1))                   # tensorflw 2.0
            Qs[0, a] = reward + dis * np.max(Qs1)

        #sess.run(train, feed_dict={X: one_hot(s), Y:Qs}) # tensorflw 1.0
        model.fit(one_hot(s), Qs)                         # tensorflw 2.0

        rAll += reward
        s = s1

    rList.append(rAll)

print("Percent of successful episodes :" + str(sum(rList) / num_episodes) + "%")

 

tensorflow 2.0으로 전체 코드를 변경한 경우, command 창에 아래와 같이 출력이 되는 걸 확인할 수 있다.