🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1757閲覧

Python,class,インスタンスからメンバー追加したが、AttribureErrorが発生する

Por

総合スコア40

Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/02/06 05:30

前提・実現したいこと

よろしくお願いいたします。

インスタンスへのメンバー追加とクラスへのメンバー追加の違い
メンバー追加の正しい方法
を確認したいと思っております。
ご教授いただけますと幸いです。

発生している問題・エラーメッセージ

AttributeError: 'WindowGenerator' object has no attribute 'example'

該当のソースコード

Python3.6.9

1# -*- coding: utf-8 -*- 2 3import os 4import datetime 5 6import IPython 7import IPython.display 8import matplotlib as mpl 9import matplotlib.pyplot as plt 10import numpy as np 11import pandas as pd 12import seaborn as sns 13import tensorflow as tf 14 15mpl.rcParams['figure.figsize'] = (12,9) 16mpl.rcParams['axes.grid'] = False 17 18import requests 19from PIL import Image 20from io import BytesIO 21 22def image(url): 23 req = requests.get(url) 24 return Image.open(BytesIO(req.content)) 25 26import pandas_datareader.data as pdr 27 28df = pdr.DataReader('aapl', 'yahoo', '2018/01/01') 29df['Date Time'] = df.index 30df.reset_index(inplace=True) 31date_time = pd.to_datetime(df.pop('Date Time'), format='%d.%m.%Y %H:%M:%S') 32df.drop(columns='Date', inplace=True) 33 34 35# converting it to seconds: 36timestamp_s = date_time.map(datetime.datetime.timestamp) 37 38# del print 39 40day = 24*60*60 41year = (365.2425)*day 42 43df['Day sin'] = np.sin(timestamp_s * (2*np.pi/day)) 44df['Day cos'] = np.cos(timestamp_s * (2*np.pi/day)) 45df['Year sin'] = np.sin(timestamp_s * (2*np.pi/year)) 46df['Year cos'] = np.cos(timestamp_s * (2*np.pi/year)) 47 48# plt.plot(np.array(df['Day sin'])) 49# # plt.plot(np.array(df['Day cos'])) 50# plt.xlabel('Time [h]') 51# plt.title('Time of day signal') 52 53 54 55 56 57"""## Split data""" 58 59column_indices = {name:i for i, name in enumerate(df.columns)} 60 61n = len(df) 62train_df = df[0:int(n*0.7)] 63val_df = df[int(n*0.7):int(n*0.9)] 64test_df = df[int(n*0.9):] 65num_features = df.shape[1] 66 67train_mean = train_df.mean() 68train_std = train_df.std() 69 70train_df = (train_df - train_mean) / np.maximum(train_std, 1e-12) 71val_df = (val_df - train_mean) / np.maximum(train_std, 1e-12) 72test_df = (test_df - train_mean) / np.maximum(train_std, 1e-12) 73 74 75df_std = (df - train_mean) / np.maximum(train_std, 1e-12) 76df_std = df_std.melt(var_name='Column', value_name='Normalized') 77 78 79 80 81 82"""# Data windowing""" 83 84class WindowGenerator(): 85 def __init__(self, input_width, label_width, shift, 86 train_df=train_df, val_df=val_df, test_df=test_df, 87 label_columns=None): 88 self.train_df = train_df 89 self.val_df = val_df 90 self.test_df =test_df 91 92 # for column indices of 'Label' 93 self.label_columns = label_columns 94 if label_columns is not None: 95 self.label_columns_indices = {name:i for i,name in enumerate(label_columns)} 96 self.column_indices = {name:i for i,name in enumerate(label_columns)} 97 98 # for window params 99 self.input_width = input_width 100 self.label_width = label_width 101 self.shift = shift 102 self.total_window_size = input_width + shift 103 self.input_slice = slice(0, input_width) 104 self.input_indices = np.arange(self.total_window_size)[self.input_slice] 105 self.label_start = self.total_window_size - self.label_width 106 self.label_slice = slice(self.label_start, None) 107 self.label_indices = np.arange(self.total_window_size)[self.label_slice] 108 109 110 def __repr__(self): 111 return '\n'.join([ 112 f'Total window size: {self.total_window_size}', 113 f'Input indices: {self.input_indices}', 114 f'Label indices: {self.label_indices}', 115 f'Label column name(s): {self.label_columns}' 116 ]) 117 118 119# 2 samples 120w1 = WindowGenerator(input_width=24, label_width=1, shift=1, label_columns=['Adj Close']) 121w1 122 123w2 = WindowGenerator(input_width=6, label_width=1, shift=1, label_columns=['Adj Close']) 124w2 125 126 127 128def split_window(self, features): 129 inputs = features[:, self.input_slice, :] 130 labels = features[:, self.label_slice, :] 131 if self.label_columns is not None: 132 labels = tf.stack( 133 [labels[:, :, self.column_indices[name]] for name in self.label_columns], 134 axis=-1) 135 inputs.set_shape([None, self.input_width, None]) 136 labels.set_shape([None, self.label_width, None]) 137 138 return inputs, labels 139 140WindowGenerator.split_window = split_window 141 142 143 144 145# stack 3 slices,, 146 147exam_window = tf.stack([ 148 np.array(train_df[:w2.total_window_size]), 149 np.array(train_df[100:100+w2.total_window_size]), 150 np.array(train_df[200:200+w2.total_window_size]) 151]) 152 153exam_inputs, exam_labels = w2.split_window(exam_window) 154 155print('All shapes: (batch, time, features)') 156print(f'Window shape: {exam_window.shape}') 157print(f'Inputs shape: {exam_inputs.shape}') 158print(f'Labels shape: {exam_labels.shape}') 159 160w2.example = exam_inputs, exam_labels 161 162 163 164def plot(self, model=None, plot_col='Adj Close', max_subplot=3): 165 inputs, labels = self.example 166 plt.figure(figsize=(12,8)) 167 plot_col_index = self.column_indices[plot_col] 168 max_n = min(max_subplot, len(inputs)) 169 for n in range(max_n): 170 plt.subplot(3, 1, n+1) 171 plt.ylabel(f'{plot_col} [normed]') 172 plt.plot(self.input_indices, inputs[n, :, plot_col_index], 173 label='Inputs', marker='.', zorder=-10) 174 175 if self.label_columns: 176 label_col_index = self.label_columns_indices.get(plot_col, None) 177 else: 178 label_col_index = plot_col_index 179 180 if label_col_index is None: 181 continue 182 183 plt.scatter(self.label_indices, labels[n, :, label_col_index], 184 edgecolors='k', label='Labels', c='#2ca02c', s=64) 185 186 if model is not None: 187 predictions = model(inputs) 188 plt.scatter(self.label_indices, predictions[n, :, label_col_index], 189 marker='X', edgecolors='k', label='Predictions', c='#ff7f0e', s=64) 190 191 if n==0: 192 plt.legend() 193 194 plt.xlabel('Time [h]') 195 196 197WindowGenerator.plot = plot 198 199 200 201 202 203 204def make_dataset(self, data): 205 data = np.array(data, dtype=np.float32) 206 ds = tf.keras.preprocessing.timeseries_dataset_from_array( 207 data=data, 208 targets=None, 209 sequence_length=self.total_window_size, 210 sequence_stride=1, 211 shuffle=True, 212 batch_size=32, 213 ) 214 215 ds = ds.map(self.split_window) 216 217 return ds 218 219 220WindowGenerator.make_dataset = make_dataset 221 222 223 224@property 225def train(self): 226 return self.make_dataset(self.train_df) 227 228@property 229def val(self): 230 return self.make_dataset(self.val_df) 231 232@property 233def test(self): 234 return self.make_dataset(self.test_df) 235 236WindowGenerator.train = train 237WindowGenerator.val = val 238WindowGenerator.test = test 239 240 241 242 243 244for exam_inputs, exam_labels in w2.train.take(1): 245 print(f'Inputs shape (batch, time, features): {exam_inputs.shape}') 246 print(f'Labels shape (batch, time, features): {exam_labels.shape}') 247 248 249 250 251# by Dense 252 253MAX_EPOCHS = 20 254 255def compile_and_fit(model, window, patience=2): 256 early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', 257 patience=patience, 258 mode='min') 259 model.compile(loss=tf.losses.MeanSquaredError(), 260 optimizer=tf.optimizers.Adam(), 261 metrics=[tf.metrics.MeanAbsoluteError()]) 262 263 history = model.fit(window.train, epochs=MAX_EPOCHS, 264 validation_data=window.val, 265 callbacks=[early_stopping]) 266 267 return history 268 269dense = tf.keras.Sequential([ 270 tf.keras.layers.Dense(units=64, activation='relu'), 271 tf.keras.layers.Dense(units=64, activation='relu'), 272 tf.keras.layers.Dense(units=1) 273 274]) 275 276 277 278CONV_WIDTH = 20 279conv_window = WindowGenerator( 280 input_width=CONV_WIDTH, 281 label_width=1, 282 shift=1, 283 label_columns=['Adj Close'] 284) 285 286 287 288 289multi_step_dense = tf.keras.Sequential([ 290 # Shape: (time, features) => (time*features) 291 tf.keras.layers.Flatten(), 292 tf.keras.layers.Dense(units=32, activation='relu'), 293 tf.keras.layers.Dense(units=32, activation='relu'), 294 tf.keras.layers.Dense(units=1), 295 # Add back the time dimension. 296 # Shape: (outputs) => (1, outputs) 297 tf.keras.layers.Reshape([1, -1]), 298]) 299 300 301history = compile_and_fit(multi_step_dense, conv_window) 302 303 304 305conv_window.plot() 306# AttributeError: 'WindowGenerator' object has no attribute 'example' 307 308

試したこと

インスタンスから組み込み関数dirで、メンバーを抽出できることを調べ
上記'example'がメンバーとして表示されていることを確認しました。

WindowGeneratorクラスからw2インスタンスを作成
w2.exampleと記述し、WindowGeneratorクラスへメンバーが追加できる
と認識しておりますが、、
どこか間違っているのでしょうか。

こちらのコードを参考
https://www.tensorflow.org/tutorials/structured_data/time_series
にさせていただき、何度か確認いたしましたが
こちらは
WindowGeneratorクラスへではなく、インスタンスへexampleメンバーを追加することで
その後のplot()メソッドも実行できておりました。

その違いがわからずとなっており
ご教授いただけますと幸いです。

補足情報(FW/ツールのバージョンなど)

python3.6.9
Google Colab

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Porさんが気にしているものは、pythonではメンバーとは呼びません。pythonではメンバーという言葉は別の意味で使っていますのでインスタンス変数と呼ぶほうが良いでしょう。属性でも良いのですが、属性にはインスタンス変数やインスタンスメソッドも含むのであいまいになります。

C++やJAVAのような言語では、一つのクラスのすべてのインスタンスは同じ名前のメンバー変数や持ちますが、pythonのような言語では、一つのクラスのインスタンスがそれぞれ異なった名前のインスタンス変数を持つことが可能です。

python

1>>> class C: 2... pass 3... 4>>> c1 = C() 5>>> c2 = C() 6>>> c1.a = 100 7>>> print(c1.a) 8100 9>>> print(c2.a) 10Traceback (most recent call last): 11 File "<stdin>", line 1, in <module> 12AttributeError: 'C' object has no attribute 'a'

https://www.tensorflow.org/tutorials/structured_data/time_series
の例では、
w2.example = example_inputs, example_labels
のあとで、
w2.plot(plot_col='p (mbar)')
をやっているので問題なく動きます。

Porさんのプログラムでも

python

1conv_window = WindowGenerator( 2 input_width=CONV_WIDTH, 3 label_width=1, 4 shift=1, 5 label_columns=['Adj Close'] 6) 7conv_window.example = exam_inputs, exam_labels

としてみてはどうでしょうか。

投稿2021/02/06 11:14

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Por

2021/02/06 12:23

ご回答いただき、ありがとうございます。 メンバーと呼ばず インスタンス変数と呼ぶことについて、修正いたします。ご指摘ありがとうございます。 参照先のご確認もいただきありがとうございます。 そうでしたか、w2インスタンスでplotメソッドを呼び出しているからエラーが起きないのですね。 私のミスは 「エラー内容がWindowGeneratorクラス本体が、追加されたインスタンス変数を含んでいないことを指摘しているように読んでしまい」 「example変数追加後に作る新しいインスタンス(conv_window)は、すべてこのexampleを踏まえてインスタンスとして作成される」 と誤解してしまった ということで合ってますでしょうか。
ppaul

2021/02/06 12:39

はい、其のとおりです。
Por

2021/02/06 23:48

ありがとうございます。 もう1点お伺いできますでしょうか。 参照先では `wide_window`インスタンスの作成後、そのまま インスタンス変数exampleが必要なplotメソッドを呼び出しておりました。 参考先では事前にwide_windowインスタンスに インスタンス変数example追加をすることなく wide_windowでplotメソッドを呼び出せておりまして、、 こちらは なぜ可能となるか、教えていただくことはできますでしょうか。
ppaul

2021/02/07 02:46

不完全なコードでこのままでは動かないように見えます。 Porさんが、このコードを動かしてエラーなく動いたというのであれば、その動いたコードを載せていただければ、こちらでも再現テストしてみます。
Por

2021/02/07 06:02

ありがとうございます。 正確性を確保したくコードはそのままお見せしたいのですが わかりやすくしたものはどうしても10000文字(terateilの規制以上の文字数)となってしまい、 こちらにColabノートブックの共有リンクでの 共有をさせていただいてもよろしいでしょうか。
ppaul

2021/02/08 06:05

Colabノートブックとかはなるべく使わないようにしています。 その代わりに、以下の実験をしてみてください。 wide_windowを作成した直後に、以下のコードを入れて結果を見る。 print(hasattr(wide_window, 'example')) print('example in type(wide_window).__dict__)
Por

2021/02/10 07:26

ご回答いただきありがとうございます。 無事解決いたしました。 make_datasetメソッドのプロパティ作成後 exampleインスタンスを追加することで無事達成できました。 長らくご助力いただき、大変ありがとうございました。
guest

0

「w2.exampleと記述し、WindowGeneratorクラスへメンバーが追加できる」わけではありません。

インスタンスはクラスを雛形として生成されますが、生成されたあとは クラスの定義とつながってはいませんので、インスタンスにメンバを追加してもクラスにメンバが追加されるわけではありません。

インスタンスに追加されたメンバはそのインスタンスのみで利用可能です。

投稿2021/02/06 09:25

TakaiY

総合スコア13768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Por

2021/02/06 12:15

早速ご回答いただき、ありがとうございます。 やはりインスタンスだけに入るということだったのですね。 おかげさまで、今後は間違えることがなくなりそうです。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問