mnist = tf.keras.datasets.fashion_mnist (training_images, training_labels), (test_images, test_labels) = mnist.load_data() training_images /= 255.0 test_images /= 255.0 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation=tf.nn.relu), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ]) model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"]) model.fit(training_images, training_labels, epochs=5) test_loss = model.evaluate(test_images, test_labels)
코드 출처: C1_W3_Lab_1_improving_accuracy_using_convolutions.ipynb
텐서플로우 자격증을 준비하기 위해 코세라 강의를 듣고 실습하던 중 다음과 같은 오류가 떴다.
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-5-a45d78a6ac67> in <module>() 1 mnist = tf.keras.datasets.fashion_mnist 2 (training_images, training_labels), (test_images, test_labels) = mnist.load_data() ----> 3 training_images /= 255.0 4 test_images /= 255.0 5 model = tf.keras.models.Sequential([ ValueError: output array is read-only
training_images = training_images / 255.0랑 training_images /= 255.0는 분명 같은 거라고 배웠는데 왜 오류가 날까? 에러 내용을 구글링하니 나와 같은 고민을 하는 사람을 바로 찾을 수 있었다.
Why does /= raise an error but not x=xy with a read-only numpy array?
I've always thought x /= y is equal to x = x / y. But now I'm facing a situation that I'll have an error when I use /= but not when using x = x / y. so definitely they shouldn't be the same in pyth...
stackoverflow.com
읽기 귀찮은 사람들을 위해 간단히 말하자면 numpy array는 read-only다. 그 말은 즉슨 immutable한, 변경할 수 없는 객체라는 소리다. 그런데 /= 연산은 in-place연산이기 때문에 무조건 mutable한 객체에 대해서만 동작한다. 따라서 immutable한 객체는 아예 새로 할당을 해줘야 한다. x /= y가 아닌 x = x / y로 말이다.
결론: numpy array는 할당 연산자 사용 시 풀어서 써줘야 한다!
엥 그런데 에러가 뜨지 않고 정상적으로 잘 작동하는 경우도 있다.
import numpy as np import random from tensorflow.keras.preprocessing.image import img_to_array, load_img # Let's define a new Model that will take an image as input, and will output # intermediate representations for all layers in the previous model after # the first. successive_outputs = [layer.output for layer in model.layers[1:]] #visualization_model = Model(img_input, successive_outputs) visualization_model = tf.keras.models.Model(inputs = model.input, outputs = successive_outputs) # Let's prepare a random input image from the training set. horse_img_files = [os.path.join(train_horse_dir, f) for f in train_horse_names] human_img_files = [os.path.join(train_human_dir, f) for f in train_human_names] img_path = random.choice(horse_img_files + human_img_files) img = load_img(img_path, target_size=(300, 300)) # this is a PIL image x = img_to_array(img) # Numpy array with shape (150, 150, 3) x = x.reshape((1,) + x.shape) # Numpy array with shape (1, 150, 150, 3) # Rescale by 1/255 x /= 255 # Let's run our image through our network, thus obtaining all # intermediate representations for this image. successive_feature_maps = visualization_model.predict(x) # These are the names of the layers, so can have them as part of our plot layer_names = [layer.name for layer in model.layers[1:]] # Now let's display our representations for layer_name, feature_map in zip(layer_names, successive_feature_maps): if len(feature_map.shape) == 4: # Just do this for the conv / maxpool layers, not the fully-connected layers n_features = feature_map.shape[-1] # number of features in feature map # The feature map has shape (1, size, size, n_features) size = feature_map.shape[1] # We will tile our images in this matrix display_grid = np.zeros((size, size * n_features)) for i in range(n_features): # Postprocess the feature to make it visually palatable x = feature_map[0, :, :, i] x -= x.mean() x /= x.std() x *= 64 x += 128 x = np.clip(x, 0, 255).astype('uint8') # We'll tile each filter into this big horizontal grid display_grid[:, i * size : (i + 1) * size] = x # Display the grid scale = 20. / n_features plt.figure(figsize=(scale * n_features, scale)) plt.title(layer_name) plt.grid(False) plt.imshow(display_grid, aspect='auto', cmap='viridis')
코드 출처: C1_W4_Lab_1_image_generator_no_validation.ipynb
코드 다 볼 필요 없고 21번째 줄을 보면 x가 numpy array인데 코드 실행 시 전혀 문제가 생기지 않았다. 뭐지.....? 42, 43, 44, 45번째 줄도 마찬가지다.
결론: numpy array에서 할당 연산자 사용이 안되면 풀어서 써주자!
'TIL' 카테고리의 다른 글
HDFS 휴지통 복구, HDFS 파일 복구, HDFS 폴더 복구 (0) | 2022.07.21 |
---|---|
Conv1D, Conv2D, Conv3D 차이 (0) | 2021.11.22 |
include_top의 의미 (0) | 2021.11.17 |
입력 이미지(input image)를 정규화(normalize)하는 이유 (0) | 2021.11.11 |
sigmoid보다 tanh를 쓰는 이유 (0) | 2021.08.19 |