%tensorflow_version 2.x
import tensorflow as tf
from tensorflow import keras
import numpy as np
from sklearn.datasets import load_iris
x,y = load_iris(return_X_y=True)
x.shape, y.shape, set(y) # 150개의 데이터, 클래스 k=3

→ ((150, 4), (150,), {0, 1, 2})

#간단한 모델
simple_model = keras.Sequential()
simple_model.add(keras.layers.Dense(3, activation=keras.layers.Softmax()))
simple_model.compile(loss=keras.losses.sparse_categorical_crossentropy, metrics=['accuracy'])
#전문가 모델
class MyModel(keras.Model):
  def __init__(self):
    super(MyModel, self).__init__()#상속한 클래스의 생성자 호출 
    self.opt = tf.optimizers.SGD(learning_rate=0.01)#Stochatic Gradient Descent 확률적 경사 하강
    self.dense = keras.layers.Dense(units=3, activation=keras.activations.softmax)
  
  def call(self, x):
    h = self.dense(x)    
    return h

  def get_loss(self, y, h):
    cross_entropy = - (y * tf.math.log(h) + (1 - y) * tf.math.log(1 - h)) 
    loss = tf.reduce_mean(cross_entropy)
    return loss

  def get_accuracy(self, y, h):
    # h 3개의 확률: (m, 3), y: (m)
    predict = tf.argmax(h, -1)
    self.acc = tf.reduce_mean(tf.cast(tf.equal(y, predict), tf.float32)) # True > 1, False > 0 로 cast

  def fit(self, x, y, epoch=1):
    # x : (m, 4), y: (m)    
    y_hot = tf.one_hot(y, depth=3, axis=-1)#(m, 3)    
    for i in range(epoch):
      with tf.GradientTape() as tape: #경사 기록 장치
        h = self.call(x)
        loss = self.get_loss(y_hot, h)
      grads = tape.gradient(loss, self.trainable_variables) #경사 계산
      self.opt.apply_gradients(zip(grads, self.trainable_variables)) # 가중치에서 경사를 빼기
      self.get_accuracy(y, h)
      print('%d/%d loss:%.3f acc:%.3f'%(i, epoch, loss, self.acc))
model = MyModel()

0/1000 loss:1.103 acc:0.333

1/1000 loss:1.034 acc:0.333

2/1000 loss:0.980 acc:0.333


997/1000 loss:0.297 acc:0.913

998/1000 loss:0.297 acc:0.913

999/1000 loss:0.296 acc:0.913

model.fit(x, y, 1000)
h = model(x[:1])
print(np.array(h)) #확률

from sklearn.datasets import load_digits
data = load_digits()
x = data.images
y = data.target
x.shape, y.shape

 ((1797, 8, 8), (1797,))

x_4d = np.expand_dims(x,-1)
x_4d.shape

 (1797, 8, 8, 1)

set(y)

 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

y

 array([0, 1, 2, ..., 8, 9, 8])

y_hot = tf.one_hot(y,10)
y_hot

<tf.Tensor: shape=(1797, 10), dtype=float32, numpy=

array([[1., 0., 0., ..., 0., 0., 0.],

        [0., 1., 0., ..., 0., 0., 0.],

        [0., 0., 1., ..., 0., 0., 0.],

        ...,

        [0., 0., 0., ..., 0., 1., 0.],

        [0., 0., 0., ..., 0., 0., 1.],

                                [0., 0., 0., ..., 0., 1., 0.]], dtype=float32)>

#전문가 모델
class MyModel(keras.Model):
  def __init__(self):
    super(MyModel, self).__init__()#상속한 클래스의 생성자 호출 
    self.opt = tf.optimizers.SGD(learning_rate=0.01)#Stochatic Gradient Descent 확률적 경사 하강
    self.conv1 = keras.layers.Conv2D(32,[3,3],padding='same')
    self.maxp1 = keras.layers.MaxPool2D((2,2),padding='same')
    self.conv2 = keras.layers.Conv2D(64,[3,3],padding='same')
    self.maxp2 = keras.layers.MaxPool2D((2,2),padding='same')
    self.flatten= keras.layers.Flatten()
    self.dense = keras.layers.Dense(units=128, activation=keras.activations.relu)
    self.dense1 = keras.layers.Dense(units=64, activation=keras.activations.relu)
    self.dense2 = keras.layers.Dense(units=10, activation=keras.activations.softmax)

  def call(self, x):
    # x_4d = tf.reshape(x, [-1,8,8,1])
    h = self.conv1(x)
    h = self.maxp1(h)
    h = self.conv2(h)
    h = self.maxp2(h)
    h = self.flatten(h)
    h = self.dense(h)
    h = self.dense1(h)
    h = self.dense2(h)
    return h

  def get_loss(self, y, h):
    cross_entropy = - (y * tf.math.log(h) + (1 - y) * tf.math.log(1 - h)) 
    loss = tf.reduce_mean(cross_entropy)
    return loss

  def get_accuracy(self, y, h):
    # h 3개의 확률: (m, 3), y: (m)
    predict = tf.argmax(h, -1)
    self.acc = tf.reduce_mean(tf.cast(tf.equal(y, predict), tf.float32)) # True > 1, False > 0 로 cast

  def fit(self, x, y, epoch=1):
    # x : (m, 4), y: (m)    
    y_hot = tf.one_hot(y, depth=10, axis=1)#(m, 3)    
    for i in range(epoch):
      with tf.GradientTape() as tape: #경사 기록 장치
        h = self.call(x)
        loss = self.get_loss(y_hot, h)
      grads = tape.gradient(loss, self.trainable_variables) #경사 계산
      self.opt.apply_gradients(zip(grads, self.trainable_variables)) # 가중치에서 경사를 빼기
      self.get_accuracy(y, h)
      print('%d/%d loss:%.3f acc:%.3f'%(i, epoch, loss, self.acc))
model = MyModel()

0/1000 loss:0.404 acc:0.123

1/1000 loss:0.393 acc:0.115

2/1000 loss:0.384 acc:0.100

3/1000 loss:0.376 acc:0.091


997/1000 loss:0.021 acc:0.981

998/1000 loss:0.021 acc:0.981

999/1000 loss:0.021 acc:0.981

model.fit(x_4d,y,1000)

'Deep learning > Code' 카테고리의 다른 글

cnn_2_number  (0) 2020.01.30
keras_cnn_expert  (0) 2020.01.30
gradientDescent  (0) 2020.01.29
Convolution  (0) 2020.01.29
Multi-class  (0) 2020.01.29