진짜 일주일 내내 똥이 쌌다.
주말에도 연구실에 가서 코드만 보고 스택 오버플로 하루 종일 늦게 먼지 모인 옛날 블로그 기사도 읽었다.
그리고 ChatGPT에게 너무 묻습니다.
거의 내가 지금 내 상태.
코드를 한 번 돌릴 때마다 하나님께 기도 한 번씩 올렸다.
거의 100회 이상 기도한 것 같습니다만,
어쨌든 내가 어떻게 오류를 해결했는지 정리하고 싶습니다.
수정한 코드가 너무 많습니다만… 한번 정리해 보면…
내가 사용하려고하는 코드는 ACL2017에 게시되었습니다.
”An unsupervised neural attention model for aspect extraction논문으로 작성된 코드. 필요한 환경은 requirements.txt에서 볼 수 있습니다.
keras==1.2.1
theano==0.9.0
numpy==1.13.3
scikit-learn
gensim==0.12.4
tqdm
h5py
얼마든지 keras 1.2.1 버전과 numpy 1.13.3은 그다지 무엇이 아닐까 🤯. tensor flow 최신 버전이 2.6.0으로 알고 있는데… 어쨌든 이 모델은 이미지 하지 않는다.
꽤 구식 버전을 사용하고 있다는 것은 고쳐야 하는 것이 샌더미라는 것이다.
예를 들어, 옛날에는 tf.dot를 사용했지만 지금은 tf.matmul을 사용하는 것 같습니다.
가상 환경을 빌드 한 후에 requirements.txt처럼 설치해야하지만 이미 많은 시도와 가상 환경 빌드의 끝에 그대로 환경을 구현하면 모델을 돌릴 수 없다는 결론에 이르렀다.
그래서 단지 최신 버전으로 설치해 버렸다.
미래의 내가 코드를 고칠 수 있다고 생각했다 (수리했지만 매우 힘들었다)
내가 설치한 버전과 버전은 다음과 같습니다.
python==3.6.13
tensorflow==2.6.2
keras==2.6.0
numpy==1.19.5
scikit-learn==0.24.2
gensim==4.0.1
tqdm==4.63.0
h5py==3.1.0
nltk==3.4.5
그 밖에도 conda list에서 내가 가상 환경에 설치한 것이 무엇인지 확인해 보면 다른 것도 많은데 내가 직접 설치해준 것은 이들뿐이다.
최신 버전으로 설치한 후 model.py 및 my_layers.py로 가져오는 모델을 약간 수정했습니다.
my_layers.py
#import keras.backend as K
#from keras.engine.topology import Layer
import tensorflow as tf
from tensorflow.keras.layers import Layer, InputSpec
from tensorflow.keras import initializers, regularizers, constraints
#from tensorflow.keras import backend as K
#from keras import initializations
#from keras import regularizers
#from keras import constraints
import numpy as np
#import theano.tensor as T
주석 처리된 것이 기존의 것이며, 나머지가 새롭게 된 것…
model.py
import logging
#import keras.backend as K
#from tensorflow.keras import backend as K
from tensorflow.keras.layers import Dense, Activation, Embedding, Input
from tensorflow.keras.models import Model
from my_layers import Attention, Average, WeightedSum, WeightedAspectEmb, MaxMargin
import tensorflow as tf
기존 from keras import 아마 하는 것 tensorflow.keras 로 바꿨다.
오류가 발생한 것
1. theano
그리고, 어쨌든 theano(처음 보는;;)로 모델을 돌릴 수 없는 것 같고, 이 분들이 구현한 모델을 새롭게 tensorflow에 수정하기로 했다.
theano의 이야기는 진짜 문제가 많았다 🤬. 케라스와도 맞지 않고, 문법도 맞지 않고, 도대체 theano의 이야기를 뭔가 좋아하고 찾아 보았는데, tensorflow와 같이 대규모 기계 학습, 딥 러닝 모델을 구현하기 위해서 사용되는 것으로, 2017년 이후 업데이트가 중단되었다고 한다.
따라서 theano를 tensorflow로 대체하는 과정에서 몇 가지 구문을 수정한 것이 많다.
theano를 tensorflow로 변경하여 수정 한 문법
- Theano를 Tensorflow로 바꾸기
import tensorflow as tf
from tensorflow.keras.layers import Layer, InputSpec
from tensorflow.keras import initializers, regularizers, constraints
from tensorflow.keras import backend as K
- 초기화
Theano는 초기화를 keras.backend 대신 keras.initializations를 사용하고,
Tensorflow에서는 keras.initializations가 없으며 대신 keras.initializers를 사용합니다.
# Theano
self.init = initializations.get('glorot_uniform')
# TensorFlow
self.init = initializers.glorot_uniform()
- InputSpec
- Theano는 InputSpec을 지원하지 않습니다.
- TensorFlow에서는 InputSpec이 필요.
- 따라서 InputSpec을 다음과 같이 얻어야합니다.
- Theano는 InputSpec을 지원하지 않습니다.
from tensorflow.keras.layers import InputSpec
- 다른 여러 라이브러리의 이름 바꾸기
- 일부 라이브러리의 이름이 TensorFlow에서 변경되었습니다.
- 예를 들어, Theano에서는 keras.backend를 사용했지만 TensorFlow에서는 tensor flow.keras.backend를 사용해야 합니다.
- Theano에서는 keras.regularizers를 사용하지만 TensorFlow에서는 tensorflow.keras.regularizers를 사용합니다.
- 따라서 다음과 같이 코드를 수정
- 일부 라이브러리의 이름이 TensorFlow에서 변경되었습니다.
# Theano
from keras import regularizers
# TensorFlow
from tensorflow.keras import regularizers
- get_output_shape_for 메소드를 compute_output_shape로 변경
- TensorFlow에서는 “get_output_shape_for” 메서드 대신 “compute_output_shape” 메서드를 사용합니다.
- 따라서 다음과 같이 코드를 수정
- TensorFlow에서는 “get_output_shape_for” 메서드 대신 “compute_output_shape” 메서드를 사용합니다.
# Theano
def get_output_shape_for(self, input_shape):
return (input_shape(0), input_shape(0)(-1))
# TensorFlow
def compute_output_shape(self, input_shape):
return (input_shape(0), input_shape(0)(-1))
- 사용하지 않은 가져오기 삭제
- Theano에서 사용하는 keras.backend 및 keras.engine.topology 라이브러리는 TensorFlow에서 사용되지 않으므로 삭제
- 따라서 다음 코드 삭제
# Theano
import keras.backend as K
from keras.engine.topology import Layer
# TensorFlow
# 라이브러리 import 삭제
2. numpy, gensim
난파이도 하도록 설치했는데 또 gensim과 충돌… 아무리 문법 수리해 무엇을 해도 import numpy, import gensim이 되지 않기 때문에 시작도 할 수 없었다.
그래서 슛은 모든 것을 교체하고 다시 최신 버전에 설치. 그리고 버전이 바뀌어 문법이 맞지 않는 것도 모두 수정.
- gensim의 Word2Vec 모델 개체에 vocab 속성이 없는 대신 wv.vocab 속성을 사용합니다.
def __init__(self, emb_path, emb_dim=None):
logger.info('Loading embeddings from: ' + emb_path)
self.embeddings = {}
emb_matrix = ()
model = gensim.models.Word2Vec.load(emb_path)
self.emb_dim = emb_dim
for word in model.wv.vocab: # model.vocab 대신에 model.wv.vocab 사용
self.embeddings(word) = list(model.wv(word)) # model.wv(word) 사용
emb_matrix.append(list(model.wv(word))) # model.wv(word) 사용
if emb_dim is not None: # !
= 대신에 is not None 사용
assert self.emb_dim == len(self.embeddings('nice'))
self.vector_size = len(self.embeddings)
self.emb_matrix = np.asarray(emb_matrix)
logger.info(' #vectors: %i, #dimensions: %i' % (self.vector_size, self.emb_dim))
- gensim 4.0.0 이상에서는 KeyedVectors 클래스에서 vocab 속성이 삭제되었습니다.
대신 key_to_index 사전과 index_to_key 목록을 사용해야 합니다.
- model.vocab을 model.wv.key_to_index로 변경
- vocab.iteritems()을 vocab.items()로 변경
- model.vocab을 model.wv.key_to_index로 변경
3. Keras, Tensorflow
Keras를 가져온 결과 TensorFlow가 누락되지 않았기 때문에 Tasorflow는 특정 Python 버전에서만 작동하고 conda 가상 환경에서 3.6 버전으로 설치 한 후 모든 버전을 최신으로 설치했습니다.
기존 코드는 tensorflow 1.x로 작성되었으므로 내 가상 환경에 설치된 버전의 tensorflow 2.X 버전으로 돌아가려면 몇 가지 문법을 수정해야합니다.
- TensorFlow 2.x에서는 tf.floatx()지원되지 않기 때문에 tf.keras.backend.floatx()로 대체
- tf.sum 기능 tf.reduce_sum 로 변경
- tf.dot()->tf.matmul 에서 수정
- tf.repeat_elements를 tf.repeat로 변경
- tf.keras.backend.epsilon() 대신 tf.keras.backend.epsilon()사용
4. TypeError: add_weight() got multiple values for argument ‘name’
이것이 가장 문제가 많았다.
스택 오버플로와 옛날 블로그를 봐도 수정되지 않았던 끔찍한 에러… my_layers.py의 attention class에 build 함수가 문제를 일으킨 것이다.
class Attention(tf.keras.layers.Layer):#두개의 입력 텐서를 받아 가중치를 입력 masking함.
def __init__(self,
W_regularizer=None,
b_regularizer=None,
W_constraint=None,
b_constraint=None,
bias=True, **kwargs):
"""
Keras Layer that implements an Content Attention mechanism.
Supports Masking.
"""
self.supports_masking = True
self.init = initializers.glorot_uniform()#수정
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.bias = bias
super(Attention, self).__init__(**kwargs)
#self.input_spec = (InputSpec(ndim=3), InputSpec(ndim=3))#추가
def build(self, input_shape):
assert type(input_shape) == list
#assert len(input_shape) == 3
assert len(input_shape) == 2
self.steps = input_shape(0)(1)
self.W = self.add_weight(shape=(input_shape(0)(-1), input_shape(1)(-1)),
initializer=self.init,
name="{}_W".format(self.name),
regularizer=self.W_regularizer,
constraint=self.W_constraint)
if self.bias:
self.b = self.add_weight(shape=(1,),
initializer="zero",
name="{}_b".format(self.name),
regularizer=self.b_regularizer,
constraint=self.b_constraint)
self.built = True
이 오류는 class Attention (레이어)->class Attention(tf.keras.layers.Layer)로 수정하십시오. attention class에 Layer 들어간 것은 모두 수리해 주었다.
https://foxtrotin./527 여기에 해결책을 얻었다 … 고마워 …
5. TypeError: (‘Keyword argument not understood:’, ‘input’)
#기존
model = Model(input=(sentence_input, neg_input), output=loss)
#바꾸기
model = Model(inputs=(sentence_input, neg_input), outputs=loss)
6. ‘Embedding’ object has no attribute ‘W’
model.get_layer(‘word_emb’).W같은 형태로 Embedding 레이어 가중치를 찾을 수 없기 때문에 발생합니다.
#model.get_layer('word_emb').W.set_value(emb_reader.get_emb_matrix_given_vocab(vocab, model.get_layer('word_emb').W.get_value()))
#아래 코드로 수정
word_emb_layer = model.get_layer('word_emb')#수정한 코드
weights = word_emb_layer.get_weights()(0)#수정한 코드
new_weights = emb_reader.get_emb_matrix_given_vocab(vocab, weights)#수정한 코드
word_emb_layer.set_weights((new_weights))#수정한 코드
7. AttributeError: ‘ResourceVariable’ object has no attribute ‘set_value’
set_value가 더 이상 지원되지 않는다고합니다.
대신 assign() 메서드를 사용합니다.
8. AttributeError: ‘generator’ object has no attribute ‘next’
sen_gen.next() 는 파이썬 2에서 사용되는 코드이며 파이썬 3에서는 다음 (sen_gen)로 변경
9. AttributeError: ‘int’ object has no attribute ‘eval’
TensorFlow 버전 문제. TensorFlow 버전 2.0 이상에서는 TensorShape 개체의 eval()메서드가 삭제되었습니다.
그러므로 eval()사용하는 부분 수정
10. AttributeError: ‘Embedding’ object has no attribute ‘W’
‘Embedding’ 객체에는 ‘W’ 속성이 없습니다.
대신 ‘weights’ 속성을 사용하여 포함된 레이어의 가중치를 얻을 수 있습니다.
#기존
'model.get_layer('word_emb').W.get_value()'
#수정
word_emb = model.get_layer('word_emb').get_weights()(0)
이 외에도 고치는 경우가 많지만.. 일단 대략적인 버전이나 라이브러리와 관련된 오류는 모두 정리했다 …
이제 train.py도 반환하고 evaluation.py도 반환합니다.
지금 연구해야