利用規約
[서비스 이용약관] 공고일자 : 2020년 07월 11일 시행일자 : 2020년 07월 11일 [오디션 허브 이용약관] 제1조(목적) 이 약관은 '오디션 허브'에서 제공하는 오디션 등록, 관리, 신청, 지원 등 '오디션 허브'의 서비스 전반에 있어 '오디션 허브' 및 이용자의 권리, 의무, 책임 사항을 규정함을 목적으로 합니다. 제2조(정의) ① '허브'란 '오디션 허브'를 의미하며 , '회사'란 '오디션 허브'를 운영하는 '주식회사 린허브'를 의미합니다. ② '이용자'란 '오디션 허브'에 접속하여 이 약관에 따라 '오디션 허브'가 제공하는 서비스를 받는 회원 및 비회원을 말합니다. ③ ‘회원’이라 함은 '오디션 허브'에 회원 등록을 한 자로서, 계속적으로 '오디션 허브'가 제공하는 서비스를 이용할 수 있는 자를 말합니다. ④ ‘비회원’이라 함은 회원에 가입하지 않고 '오디션 허브'가 제공하는 서비스를 이용하는 자를 말합니다. ⑤ '기획사'라 함은 '오디션 허브'에 '기획사 회원 등록'을 한 회원을 말합니다. ⑥ '일반 오디션 등록'이라 함은 '오디션 허브'에서 '이용자'에게 제공하는 오디션 정보를 등록하는 것을 '허브'에게 요청하는 행위를 말한다. ⑦ '원클릭 오디션 등록'이라 함은 '오디션 허브'에서 '이용자' 및 '기획사'에게 제공하는 오디션 정보 및 오디션 관리 시스템을 등록하는 것을 '기획사'가 '허브'에게 요청하는 행위를 말한다. 제3조 (약관 등의 명시와 설명 및 개정) ① 본 약관은 '이용자'가 회원 가입 시 약관의 내용에 동의하고, '허브'에 그 회원 가입 신청이 정상적으로 승인, 등록 된 시점에서 효력이 발생합니다. ② 덧붙여 본 약관은 '이용자' 및 '기획사'가 '허브'에서 제공하는 오디션 등록 서비스인 '일반 오디션 등록' 및 '원클릭 오디션 등록'을 이용한 시점에서 효력이 발생합니다. ③ '허브'는 본 약관의 내용을 '이용자'가 알 수 있도록 홈페이지 하단에 연결 링크를 제공하는 방식으로 '이용자'에게 공지합니다. ④ '허브'는 본 약관을 변경할 수 있되, 본 약관을 변경하고자 할 때에는 적용 일자, 개정 내용 등을 명시하여 7일 전에 약관을 공지하여야 하며 변경된 개정 약관 적용에 대한 회원의 동의 여부를 확인하여야 합니다. 개정 약관에 동의 및 거부 의사를 표하지 않는 '이용자'의 경우 '허브'는 동의한 것으로 간주할 수 있습니다. ⑤ '이용자'는 '허브'의 변경된 약관에 동의하지 않는 경우 '허브'의 서비스 이용 계약을 해지할 수 있습니다. 이때 서비스 이용 계약 해지라함은 '회원 탈퇴'를 의미합니다. ⑥ '이용자'는 '허브'는가 제공하는 서비스를 이용함에 있어 관련 법령을 최우선적으로 준수해야 하며, 이 약관 규정을 들어 관련 법령 위반에 대한 면책을 주장할 수 없습니다. ⑦ '허브'는 홈페이지 내부 개별 서비스에 대하여 별도의 이용 약관 및 운영 정책을 둘 수 있으며, 해당 운영 정책과 본 약관이 상충할 경우 개별 운영 정책을 우선적으로 적용합니다. 제4조(서비스 전반 및 의무) ① '허브'는 다음과 의무를 가집니다. 1. '허브'는 본 약관이 금지하거나 미풍양속에 반하는 행위를 하지 않으며, '이용자'에게 리가 될 수 있는 지속적이고 안정적인 서비스를 제공하는 것에 최선을 다하여야 합니다. 2. '허브'는 '이용자'의 개인 신상 정보를 '이용자' 개인의 동의 없이 제 3자에게 누설, 배포 하지 않습니다. 단, 관계 법령에 의하여 국가 기관의 요구나 그에 준하는 기관의 요청 등 당국 법률 규정에 따른 적법한 절차에 의한 요구는 본 조항을 이행할 의무가 없습니다. 3. '허브'가 제공하는 서비스로 인하여 '이용자'에게 손해가 발생한 경우 그 손해가 '허브'의 중과실 및 고의에 의하여 발생한 경우에만 책임을 부당하며, 그 책임의 범위는 통상 손해에 한합니다. ② '이용자'는 다음과 같은 의무를 가집니다. 1. '이용자'는 본 약관의 규정, 관련 법령, 운영 원칙, '허브'가 고지하는 사항을 준수해야 하며, 기타 '허브'의 서비스 제공에 방해되는 행위를 해서는 안 됩니다. 2. '이용자'는 회원 가입 신청, 변경, 오디션 등록 시 허위 내용을 등록하거나, 타인의 정보를 도용, '허브'가 게시한 정보를 임의로 변경, '허브'가 제공하는 시스템에 과부하를 가져오는 행위, '허브'가 정한 정보 이외의 정보를 송신 또는 게시, '허브'및 기타 제 3자의 저작권 등 지식재산권 침해, '허브' 및 제 3자의 명예를 손상시키거나 업무를 방해, 외설 또는 폭력적인 메세지, 화상, 음성 등 미풍양속에 반하는 정보를 '허브' 내에 공개 또는 게시하는 행위, '허브'의 동의 없이 영리를 목적으로 본 서비스를 이용하는 행위, '허브'의 이용권한, 기타 이용 계약상의 지위를 타인에게 양도 및 증여, 또는 담보로 잡는 행위, 다른 이용자의 개인 정보를 무단으로 수집하는 행위, 판촉이나 광고 등의 스팸 메시지를 다른 '이용자'에게 송신하는 행위, 자신의 ID와 비밀번호를 제 3자에게 제공, 이용하게 하는 행위, 특정 인물 비하, 인종차별과 같은 인신 공격적인 내용을 게시하는 행위, '허브' 또는 다른 회원 및 그 외의 제 3자에 대한 비방중상, 사기 협박, 또는 업무의 방해 행위, 본 서비스의 소스 코드의 해석을 목적으로 한 행위, '허브'의 버그나 오류 작동을 유인 또는 이용하는 행위 등 회사가 부적절하다고 판단하며 불법적이거나 부당한 행위를 하여서는 안 됩니다. 3. '기획사'는 '허브'의 서비스를 통하여 제공받은 '이용자'의 신상 정보를 제 3자에게 누설, 배포, 판매 하는 행위를 하여서는 안되며 해당 '이용자'의 신상 정보가 제 3자에게 유출되지 않도록 최대한의 노력을 가해야 합니다. 제5조(오디션 등록 및 원클릭 오디션 신청) ① '이용자'는 '허브'를 통하여 오디션을 게재 할 때 허위 사실을 등록하지 않아야 하며 이를 위반하여 발생되는 피해는 일절 '허브'에서 책임을 지지 않습니다. ② '이용자'가 '허브'를 통하여 오디션에 지원할 때, '허브' 및 '기획사'는 해당 오디션에 지원한 '이용자'가 해당 오디션을 관리하는 '허브' 및 '기획사'에게 자신의 개인 정보를 전달하는 것을 동의한 것으로 간주합니다. ③ '이용자'가 '허브'를 통하여 오디션을 게재 할 때 '허브'는 '이용자'에게서 받은 정보를 토대로 '허브'에 오디션을 게재합니다. 오디션이 정상적으로 등록 되었을 때 '이용자'는 '허브'에게 전달 해준 정보 및 파일, 이미지 등의 '지적재산권 침해' 문제를 '허브'에게 제기할 수 없습니다. ④ '허브'는 '이용자'의 오디션 지원 신청 등으로 발생한 '기획사' 및 제 3자간의 분쟁에 일체 책임을 지지 않으며, '기획사'가 '허브'를 통하여 게재한 오디션을 통하여 발생한 '이용자'와의 분쟁에도 일체 책임을 지지 않습니다. 제6조(콘텐츠, 권한, 라이센스 및 이용자 게시물 저작권) ① '이용자'가 '허브'내에 게시한 게시물을 저작권 법의 보호를 받으며, '허브'가 작성한 저작물에 대한 저작권 및 기타 지적재산권은 '허브'를 운영하는 '회사'에 귀속됩니다. ② '이용자'는 '허브'내에 게재된 정보 및 오디션 지원 정보 등을 '허브'가 자사의 홍보를 위한 목적으로 미디어, 통신사 등에 콘텐츠 내용을 보도, 방영하게 하는 것을 허락하며, 여타 서비스 내에서 '허브'가 콘텐츠의 크기를 변환하거나 단순 방식으로 수정하는 것, '허브' 및 '허브'의 관계사가 운영하는 본 서비스의 연동 서비스에 콘텐츠를 복제, 전송, 전시하는 것을 허락합니다. 단, '이용자'가 게시물의 복제, 전송, 전시에 대한 반대 의견을 '허브'를 통하여 관리자에게 통지할 경우에는 그러하지 않습니다. ③ '이용자'는 상기 조항 이외의 행위로 '허브'가 '이용자'의 게시물 및 콘텐츠를 이용할 때에는 사전에 '이용자'의 동의를 구하기 위해 금전적 대가를 지급하는 등의 행위를 통하여 '이용자'의 동의를 구한다면 상기 조항 이외의 행위도 허락합니다. 제7조(회원 탈퇴 및 자격 상실 등) ① '이용자'는 '허브'에 언제든지 탈퇴 요청을 할 수 있으며, '허브'는 확인 즉시 회원 탈퇴를 처리합니다. ② '허브'는 하단의 각 사유에 해당하는 경우 '이용자'의 계정 및 서비스 이용을 중단 시킬 수 있습니다. 1. 가입 신청 시에 허위 내용을 등록한 경우 2. 다른 사람의 '허브' 이용을 방해하거나 그 정보를 도용하는 등 질서를 위협하는 경우 3. 기타 '허브'에서 '이용자'의 행위가 운영에 방해가 된다고 판단한 경우 제8조(분쟁의 해결) ① '허브'와 '이용자' 간 제기된 소송은 대한민국 법을 준거법으로 합니다. ② '허브'와 '이용자' 간 발생한 분쟁에 대하여는 '허브'를 운영하는 '회사'가 속한 시, 구의 법원을 전속적 합의 관할 법원으로 지정합니다.


  import numpy as np
  import matplotlib.pyplot as plt

  # 입력 데이터
  X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
  # 정답 레이블
  y = np.array([[0], [1], [1], [0]])

  # 시그모이드 활성화 함수
  def sigmoid(x):
      return 1 / (1 + np.exp(-x))

  # 시그모이드의 도함수
  def sigmoid_derivative(x):
      return x * (1 - x)

  # 신경망 클래스
  class NeuralNetwork:
      def __init__(self, input_size, hidden_size, output_size):
          # 가중치 초기화
          self.U = np.array([[0.2, 0.2, 0.3], [0.3, 0.1, 0.2]])
          self.W = np.array([[0.3, 0.2], [0.1, 0.4], [0.2, 0.3]])
          # 편향 초기화
          self.b1 = np.zeros((1, hidden_size))
          self.b2 = np.zeros((1, output_size))
          # 에포크와 오차 기록을 위한 리스트
          self.epochs = []
          self.errors = []

      def forward(self, X):
          # 은닉층 계산
          self.hidden_layer = sigmoid(np.dot(X, self.U) + self.b1)
          # 출력층 계산
          self.output_layer = sigmoid(np.dot(self.hidden_layer, self.W) + self.b2)

      def backward(self, X, y, learning_rate):
          # 출력층의 오차 계산
          output_error = y - self.output_layer
          output_delta = output_error * sigmoid_derivative(self.output_layer)

          # 은닉층의 오차 계산
          hidden_error = np.dot(output_delta, self.W.T)
          hidden_delta = hidden_error * sigmoid_derivative(self.hidden_layer)

          # 가중치 및 편향 업데이트
          self.U += learning_rate * np.dot(X.T, hidden_delta)
          self.W += learning_rate * np.dot(self.hidden_layer.T, output_delta)
          self.b1 += learning_rate * np.sum(hidden_delta, axis=0)
          self.b2 += learning_rate * np.sum(output_delta, axis=0)

      def train(self, X, y, epochs, learning_rate):
          for epoch in range(epochs):
              self.forward(X)
              self.backward(X, y, learning_rate)
              self.epochs.append(epoch + 1)
              self.errors.append(np.mean(np.abs(y - self.output_layer)))

      def predict(self, X):
          self.forward(X)
          return self.output_layer

  # 신경망 모델 생성
  input_size = 2
  hidden_size = 3
  output_size = 2
  learning_rate = 1.0
  epochs = 1000

  model = NeuralNetwork(input_size, hidden_size, output_size)
  # 모델 훈련
  model.train(X, y, epochs, learning_rate)

  # 예측 결과 출력
  predictions = model.predict(X)
  for x, y_pred in zip(X, predictions):
      print(f"x1: {x[0]}, x2: {x[1]}, y1: {y_pred[0]:.4f}, y2: {1 - y_pred[0]:.4f}")

  # 에포크와 오차 그래프 출력
  plt.plot(model.epochs, model.errors)
  plt.xlabel('epoch')
  plt.ylabel('Error')
  plt.show()




  def sigmoid(x):
      return 1 / (1 + np.exp(-x))

  def sigmoid_derivative(x):
      return x * (1 - x)

  def mse_loss(y_true, y_pred):
      return ((y_true - y_pred) ** 2).mean()

  def forward_propagation(X, weights, biases):
      layers = [X]
      for weight, bias in zip(weights, biases):
          layers.append(sigmoid(np.dot(layers[-1], weight) + bias))
      return layers

  def back_propagation(y_true, layers, weights, biases, learning_rate=1.0):
      error = y_true - layers[-1]
      for i in reversed(range(len(weights))):
          delta = error * sigmoid_derivative(layers[i+1])
          error = np.dot(delta, weights[i].T)
          weights[i] += learning_rate * np.dot(layers[i].T, delta)
          biases[i] += learning_rate * np.sum(delta, axis=0)
      return weights, biases

  np.random.seed(0)

  weights = [
      np.random.uniform(0, 1, (1, 6)),
      np.random.uniform(0, 1, (6, 4)),
      np.random.uniform(0, 1, (4, 1))
  ]
  biases = [
      np.zeros((1, 6)),
      np.zeros((1, 4)),
      np.zeros((1, 1))
  ]

  df = pd.read_csv('nonlinear.csv')
  X = df['x'].to_numpy().reshape(-1, 1)
  y_true = df['y'].to_numpy().reshape(-1, 1)

  for _ in range(100):
      for i in range(X.shape[0]):
          layers = forward_propagation(X[i:i+1], weights, biases)
          weights, biases = back_propagation(y_true[i:i+1], layers, weights, biases)

  domain = np.linspace(0, 1, 100).reshape(-1, 1)
  y_hat = forward_propagation(domain, weights, biases)[-1]

  plt.scatter(df['x'], df['y'])
  plt.scatter(domain, y_hat, color='r')
  plt.show()


  model = keras.models.Sequential([
      keras.layers.Dense(32, activation='tanh', input_shape=(1,)),
      keras.layers.Dense(16, activation='tanh'),
      keras.layers.Dense(8, activation='tanh'),
      keras.layers.Dense(4, activation='tanh'),
      keras.layers.Dense(1, activation='tanh'),
  ])

  optimizer = keras.optimizers.SGD(learning_rate=0.1)
  model.compile(optimizer=optimizer, loss='mse')

  df = pd.read_csv('nonlinear.csv')
  X = df['x'].to_numpy()
  X = X.reshape(-1, 1)
  y_label = df['y'].to_numpy()

  model.fit(X, y_label, epochs=100)

  domain = np.linspace(0, 1, 100).reshape(-1, 1)
  y_hat = model.predict(domain)
  plt.scatter(df['x'], df['y'])
  plt.scatter(domain, y_hat, color='r')
  plt.show()


  #Iris 데이터를 입력으로 하여 Versicolor, Setosa, Virginica 3종의 품종을 구분하는 심층신경망을 아래 조건을 이용하여 구성
  import numpy as np
  import pandas as pd
  import tensorflow as tf
  from sklearn.model_selection import train_test_split
  from sklearn.preprocessing import StandardScaler
  import matplotlib.pyplot as plt

  # Iris 데이터 불러오기
  url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
  df = pd.read_csv(url, header=None)

  # 입력과 출력 데이터 분리
  X = df.iloc[:, :-1].values
  y = df.iloc[:, -1].values

  # 레이블 숫자로 매핑
  label_mapping = {
      'Iris-setosa': 0,
      'Iris-versicolor': 1,
      'Iris-virginica': 2
  }
  y = np.array([label_mapping[label] for label in y])

  # 훈련 데이터와 테스트 데이터로 분할 (stratify 옵션을 사용하여 클래스 비율 유지)
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)

  # 특성 스케일링
  scaler = StandardScaler()
  X_train = scaler.fit_transform(X_train)
  X_test = scaler.transform(X_test)

  # 신경망 모델 구성
  model = tf.keras.models.Sequential()
  model.add(tf.keras.layers.Dense(64, activation='relu', input_shape=(4,)))
  model.add(tf.keras.layers.Dropout(0.2))
  model.add(tf.keras.layers.Dense(32, activation='relu'))
  model.add(tf.keras.layers.Dense(10, activation='relu'))
  model.add(tf.keras.layers.Dense(3, activation='softmax'))

  # 모델 컴파일
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])

  # 모델 훈련
  history = model.fit(X_train, y_train, batch_size=5, epochs=30, verbose=0)

  # 테스트 데이터에 대한 정확도 평가
  _, test_accuracy = model.evaluate(X_test, y_test)

  # 그래프 출력
  plt.plot(history.history['loss'], label='Loss')
  plt.plot(history.history['accuracy'], label='Accuracy')
  plt.title('Model Loss and Accuracy')
  plt.xlabel('Epoch')
  plt.legend()
  plt.show()

  print("Test Accuracy:", test_accuracy)


  # Fashion MNIST 데이터를 이용하여 다음 조건을 만족하는 신경망을 생성 + 이미지 출력
  import tensorflow as tf
  from tensorflow import keras
  import matplotlib.pyplot as plt
  import numpy as np

  # Fashion MNIST 데이터 불러오기
  fashion_mnist = keras.datasets.fashion_mnist
  (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

  # 데이터 전처리: 0~1 사이의 값으로 스케일링
  train_images = train_images / 255.0
  test_images = test_images / 255.0

  # 모델 구성
  model = keras.Sequential([
      keras.layers.Flatten(input_shape=(28, 28)),
      keras.layers.Dense(128, activation='relu'),
      keras.layers.Dropout(0.2),
      keras.layers.Dense(32, activation='relu'),
      keras.layers.Dense(10, activation='softmax')
  ])

  # 모델 컴파일
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])

  # 모델 훈련
  history = model.fit(train_images, train_labels, batch_size=64, epochs=10, validation_split=0.25)

  # 테스트 데이터에 대한 정확도 평가
  test_loss, test_accuracy = model.evaluate(test_images, test_labels)

  # 그래프 출력
  plt.figure(figsize=(12, 5))

  # Loss 그래프
  plt.subplot(1, 2, 1)
  plt.plot(history.history['loss'], label='Training Loss')
  plt.plot(history.history['val_loss'], label='Validation Loss', linestyle='dashed')
  plt.title('Model Loss')
  plt.xlabel('Epoch')
  plt.ylabel('Loss')
  plt.legend()

  # Accuracy 그래프
  plt.subplot(1, 2, 2)
  plt.plot(history.history['accuracy'], label='Training Accuracy')
  plt.plot(history.history['val_accuracy'], label='Validation Accuracy', linestyle='dashed')
  plt.title('Model Accuracy')
  plt.xlabel('Epoch')
  plt.ylabel('Accuracy')
  plt.legend()

  plt.tight_layout()
  plt.show()


  # 첫 25개 테스트 이미지 가져오기
  test_images_subset = test_images[:25]
  test_labels_subset = test_labels[:25]

  # 이미지 분류 및 출력
  predictions = model.predict(test_images_subset)
  predicted_labels = np.argmax(predictions, axis=1)

  class_labels = {
      0: "T-shirt/top",
      1: "Trouser",
      2: "Pullover",
      3: "Dress",
      4: "Coat",
      5: "Sandal",
      6: "Shirt",
      7: "Sneaker",
      8: "Bag",
      9: "Ankle boot"
  }

  plt.figure(figsize=(10, 10))
  for i in range(25):
      plt.subplot(5, 5, i + 1)
      plt.imshow(test_images_subset[i])
      plt.title(class_labels[predicted_labels[i]])
      plt.axis('off')
  plt.tight_layout()
  plt.show()

  print("Test Accuracy:", test_accuracy)




  #Keras에서 제공하는 MNIST 데이터에 대하여 합성곱 신경망을 통한 학습을 진행하라. 6만개의 훈련 데이터를 사용하여 학습하고 1만개의 테스트 데이터를 사용하여 정확도를 검증하라
  import tensorflow as tf
  from tensorflow import keras
  from tensorflow.keras import layers

  # 시드 고정
  tf.random.set_seed(0)

  # MNIST 데이터
  (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
  x_train = x_train.astype("float32") / 255.0
  x_test = x_test.astype("float32") / 255.0

  # 과제 11-1-1
  # CNN
  model = keras.Sequential()
  model.add(layers.Conv2D(4, (2, 2), strides=(2, 2), padding="same", activation="relu", input_shape=(28, 28, 1)))
  model.add(layers.MaxPooling2D((2, 2)))

  # Flatten
  model.add(layers.Flatten())
  model.add(layers.Dense(32, activation="relu"))
  model.add(layers.Dense(10, activation="softmax"))

  model.compile(
      optimizer=keras.optimizers.Adam(learning_rate=0.001),
      loss=keras.losses.SparseCategoricalCrossentropy(),
      metrics=["accuracy"],
  )

  # 모델 학습
  model.fit(x_train, y_train, epochs=1, batch_size=32)
  test_loss, test_acc = model.evaluate(x_test, y_test)

  print("테스트 데이터의 손실값 : {:.2f}".format(test_loss))
  print("테스트 데이터의 정확도 : {:.2f}".format(test_acc))

  # 과제 11-1-2 98 % 이상되게 하라 정확도가
  # CNN
  model = keras.Sequential()
  model.add(layers.Conv2D(8, (3, 3), strides=(1, 1), padding="same", activation="relu", input_shape=(28, 28, 1)))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Conv2D(16, (3, 3), strides=(1, 1), padding="same", activation="relu"))
  model.add(layers.MaxPooling2D((2, 2)))

  # Flatten
  model.add(layers.Flatten())
  model.add(layers.Dense(128, activation="relu"))
  model.add(layers.Dense(10, activation="softmax"))

  model.compile(
      optimizer=keras.optimizers.Adam(learning_rate=0.001),
      loss=keras.losses.SparseCategoricalCrossentropy(),
      metrics=["accuracy"],
  )

  # 모델 학습
  model.fit(x_train, y_train, epochs=1, batch_size=32)
  test_loss, test_acc = model.evaluate(x_test, y_test)

  print("테스트 데이터의 손실값 : {:.2f}, 테스트 데이터의 정확도 : {:.2f}".format(test_loss, test_acc))

  # Keras에서 Fashion MNIST 데이터를 불러와 아래와 같은 신경망을 구성하고 테스트 데이터에 대해 정확도를 계산하라
  import tensorflow as tf
  from tensorflow import keras
  from tensorflow.keras import layers
  import matplotlib.pyplot as plt

  # Fashion MNIST 데이터 로드
  (x_train, y_train), (x_test, y_test) = keras.datasets.fashion_mnist.load_data()
  x_train = x_train.reshape(-1, 28, 28, 1).astype("float32") / 255.0
  x_test = x_test.reshape(-1, 28, 28, 1).astype("float32") / 255.0
  y_train = keras.utils.to_categorical(y_train, num_classes=10)
  y_test = keras.utils.to_categorical(y_test, num_classes=10)

  # 모델 생성
  model = keras.Sequential()
  model.add(layers.Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Conv2D(64, (3, 3), activation="relu"))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Conv2D(32, (3, 3), activation="relu"))
  model.add(layers.Flatten())

  # DENSE
  model.add(layers.Dense(1568, activation="relu"))
  model.add(layers.Dense(128, activation="relu"))
  model.add(layers.Dense(32, activation="relu"))

  # 출력층
  model.add(layers.Dense(10, activation="softmax"))

  # 과제 11-2-1
  # 모델 출력
  model.compile(
      optimizer=keras.optimizers.Adam(),
      loss=keras.losses.CategoricalCrossentropy(),
      metrics=["accuracy"],
  )
  model.fit(x_train, y_train, epochs=1)
  _, test_acc = model.evaluate(x_test, y_test)
  print("테스트 정확도: {}".format(test_acc))

  # 과제 11-2-2
  # 테스트 이미지 분류 및 출력
  x_test_subset = x_test[:25]
  y_test_subset = y_test[:25]
  predictions = model.predict(x_test_subset)
  predicted_labels = tf.argmax(predictions, axis=1).numpy()
  class_labels = [
      "T-shirt/top",
      "Trouser",
      "Pullover",
      "Dress",
      "Coat",
      "Sandal",
      "Shirt",
      "Sneaker",
      "Bag",
      "Ankle boot"
  ]

  plt.figure(figsize=(10, 10))
  for i in range(25):
      plt.subplot(5, 5, i + 1)
      plt.imshow(x_test_subset[i].reshape(28, 28))
      plt.title(class_labels[predicted_labels[i]])
      plt.axis('off')
  plt.tight_layout()
  plt.show()



  #51개의 시퀀스를 가지는 Sine 함수 100개를 생성하고, 마지막 시퀀스의 값(51번째 값)을 예측하는 모델을 RNN, LSTM, GRU를 이용하여 구현하고 그래프를 출력
  import numpy as np
  import matplotlib.pyplot as plt
  from tensorflow.keras.models import Sequential
  from tensorflow.keras.layers import SimpleRNN, LSTM, GRU, Dense
  from sklearn.metrics import mean_squared_error

  # 데이터 생성
  x = np.arange(0, 10.2, 0.2)
  num_samples = 100
  num_sequences = 51
  start_points = np.random.choice(100, num_samples)
  dataset = []
  for start in start_points:
      y = np.sin(x + start)
      dataset.append(y)
  dataset = np.array(dataset)
  X = dataset[:, :50]
  y = dataset[:, -1]

  # 모델 생성
  model_list = [SimpleRNN, LSTM, GRU]


  for i, model_name in enumerate(model_list):

      X_train, X_test, y_train, y_test = X[:80], X[80:], y[:80], y[80:]
      model = Sequential()
      model.add(model_name(10, input_shape=(50, 1)))
      model.add(Dense(1))
      model.compile(optimizer='adam', loss='mean_squared_error')

      # 모델 학습
      history = model.fit(X_train[:, :, np.newaxis], y_train, epochs=50, verbose=0)
      y_train_pred = model.predict(X_train[:, :, np.newaxis])
      y_test_pred = model.predict(X_test[:, :, np.newaxis])
      train_mse = mean_squared_error(y_train, y_train_pred)
      test_mse = mean_squared_error(y_test, y_test_pred)

      # 출력
      fig, axs = plt.subplots(2, 2, figsize=(10, 8))
      axs[0, 0].plot(history.history['loss'])
      axs[0, 0].set_xlabel('epoch')
      axs[0, 0].set_ylabel('loss')

      axs[1, 0].plot(y_train, label='Train Actual', color='black', linewidth=2.0)
      axs[1, 0].plot(y_train_pred, label='Train Predicted', color='red')
      axs[1, 0].set_title('Train')
      axs[1, 0].legend(loc='upper right')

      axs[0, 1].scatter(y_train, y_train_pred, label='Train', marker='o')
      axs[0, 1].scatter(y_test, y_test_pred, label='Test', color='orange', marker='o')
      axs[0, 1].set_xlabel('y')
      axs[0, 1].set_ylabel('y_hat')
      axs[0, 1].legend(loc='upper left')

      axs[1, 1].plot(y_test, label='Test Actual', color='black', linewidth=2.0)
      axs[1, 1].plot(y_test_pred, label='Test Predicted', color='red')
      axs[1, 1].set_title('Test')
      axs[1, 1].legend(loc='upper right')

      axs[1, 0].text(0.05, 0.9, f'MSE: {train_mse:.5f}', transform=axs[1, 0].transAxes)
      axs[1, 1].text(0.05, 0.9, f'MSE: {train_mse:.5f}', transform=axs[1, 1].transAxes)

      plt.tight_layout()
      plt.show()