プライバシーポリシー
주식회사 린허브(이하 '린허브')는 「개인정보 보호법」 제30조에 따라 정보주체의 개인정보를 보호하고 이와 관련한 고충을 신속하고 원활하게 처리할 수 있도록 하기 위하여 다음과 같이 개인정보 처리방침을 수립·공개합니다. ○ 이 개인정보처리방침은 2021년 10월 1일부터 적용됩니다. 제1조(개인정보의 처리 목적) 린허브는 다음의 목적을 위하여 개인정보를 처리합니다. 처리하고 있는 개인정보는 다음의 목적 이외의 용도로는 이용되지 않으며 이용 목적이 변경되는 경우에는 「개인정보 보호법」 제18조에 따라 별도의 동의를 받는 등 필요한 조치를 이행할 예정입니다. 1. 홈페이지 회원가입 및 관리 회원 가입의사 확인, 회원제 서비스 제공에 따른 본인 식별·인증, 회원자격 유지·관리, 서비스 부정이용 방지, 각종 고지·통지, 고충처리 목적으로 개인정보를 처리합니다. 2. 민원사무 처리 민원 등록자의 신원 확인, 민원사항 확인, 사실조사를 위한 연락·통지, 처리결과 통보 목적으로 개인정보를 처리합니다. 3. 재화 또는 서비스 제공 서비스 제공, 콘텐츠 제공, 맞춤서비스 제공, 본인인증, 연령인증, 요금결제·정산을 목적으로 개인정보를 처리합니다. 4. 마케팅 및 광고에의 활용 신규 서비스(제품) 개발 및 맞춤 서비스 제공, 이벤트 및 광고성 정보 제공 및 참여기회 제공 , 인구통계학적 특성에 따른 서비스 제공 및 광고 게재 , 서비스의 유효성 확인, 접속빈도 파악 또는 회원의 서비스 이용에 대한 통계 등을 목적으로 개인정보를 처리합니다. 제2조(개인정보의 처리 및 보유 기간) ① 린허브는 법령에 따른 개인정보 보유·이용기간 또는 정보주체로부터 개인정보를 수집 시에 동의받은 개인정보 보유·이용기간 내에서 개인정보를 처리·보유합니다. ② 각각의 개인정보 처리 및 보유 기간은 다음과 같습니다. 1.홈페이지 회원가입 및 관리 홈페이지 회원가입 및 관리와 관련한 개인정보는 수집.이용에 관한 동의일로부터지체없이 파기까지 위 이용목적을 위하여 보유, 이용됩니다. 보유근거 : 회원 탈퇴 시 지체없이 파기 관련법령 : 1)신용정보의 수집/처리 및 이용 등에 관한 기록 : 3년 2) 대금결제 및 재화 등의 공급에 관한 기록 : 5년 예외사유 : 결제 정보, 결제 잔액 등이 남아있는 경우 관련 법령에 의거하여 최대 5년간 보존 2.민원사무 처리 민원사무 처리와 관련한 개인정보는 수집.이용에 관한 동의일로부터 3년까지 위 이용목적을 위하여 보유, 이용됩니다. 보유근거 : 관련 법령에 의거하여 불만 또는 분쟁처리에 관한 기록은 3년간 보존 관련법령 : 소비자의 불만 또는 분쟁처리에 관한 기록 : 3년 예외사유 : 단순 제안, 건의 사항 등의 이용자 개인의 정보가 포함되어 있지 않은 정보에 한하여 서비스 품질 개선을 위하여 영구 보존 3.재화 또는 서비스 제공 재화 또는 서비스 제공과 관련한 정보는 관련 법령에 의거하여 최대 5년까지 보유, 이용됩니다. 보유근거 : 회원 탈퇴 시 지체없이 파기 관련법령 : 1)신용정보의 수집/처리 및 이용 등에 관한 기록 : 3년 2) 대금결제 및 재화 등의 공급에 관한 기록 : 5년 예외사유 : 그 외 법령에 의거해 5년 이상 보존될 필요가 있는 정보는 별도로 보유, 이용됩니다. 4.마케팅 및 광고에의 활용 마케팅 및 광고에의 활용와 관련한 개인정보는 수집, 이용에 관하여 영구적으로 보유, 이용됩니다. 보유근거 : 사전 고지 내용에 한하여 마케팅 및 광고에의 활용 정보는 서비스 품질 개선을 위하여 영구 보존 예외사유 : 사전 고지 이력이 없거나 합의 내용이 존재하지 않는 경우 지체없이 즉시 파기 제3조(개인정보의 제3자 제공) ① 린허브는 개인정보를 제1조(개인정보의 처리 목적)에서 명시한 범위 내에서만 처리하며, 정보주체의 동의, 법률의 특별한 규정 등 「개인정보 보호법」 제17조 및 제18조에 해당하는 경우에만 개인정보를 제3자에게 제공합니다. ② 린허브는 다음과 같이 개인정보를 제3자에게 제공하고 있습니다. 1. 린허브 서비스 이용 및 유료 서비스 이용 용도의 정보 처리 개인정보를 제공받는 자 : 주식회사 린허브 및 린허브 내 유료 서비스 판매 주체 (창작자, 번역가 등) 제공받는 개인정보 : 이메일, 성별, 생년월일, 결제기록, 국가 제공받는 자의 개인정보 이용목적 : 린허브 서비스 이용 및 유료 서비스 이용 용도 제공받는 자의 보유, 이용기간: 법령에 의거하여 보존될 필요가 없을 경우 지체없이 파기 2. 서비스 품질 개선 및 마케팅 용도의 정보 처리 개인정보를 제공받는 자 : 주식회사 린허브 및 린허브 협력 서비스 제공받는 개인정보 : 이메일, 성별, 생년월일, 결제기록, 국가 제공받는 자의 개인정보 이용목적 : 서비스 품질 개선 및 린허브, 협력 서비스 마케팅 용도 제공받는 자의 보유, 이용기간 : 이용목적에 따른 영구 보존 제4조(개인정보처리 위탁) ① 린허브는 원활한 개인정보 업무처리를 위하여 개인정보 처리를 타인에게 위탁할 수 있습니다. 이 경우 관계 법령에 의거하여 위탁 계약 시 개인정보가 안전하게 관리될 수 있도록 필요한 조치를 취합니다. 1. 린허브 유료 서비스 이용 결제 처리 및 관리 위탁받는 자 (수탁자) : 다날, 토스페이먼츠, 카카오페이, 네이버페이 2. 본인인증 정보 처리 및 관리 위탁받는 자 (수탁자) : 다날 ② 린허브는 위탁계약 체결시 「개인정보 보호법」 제26조에 따라 위탁업무 수행목적 외 개인정보 처리금지, 기술적․관리적 보호조치, 재위탁 제한, 수탁자에 대한 관리․감독, 손해배상 등 책임에 관한 사항을 계약서 등 문서에 명시하고, 수탁자가 개인정보를 안전하게 처리하는지를 감독하고 있습니다. ③ 위탁업무의 내용이나 수탁자가 변경될 경우에는 지체없이 본 개인정보 처리방침을 통하여 공개하도록 하겠습니다. 제5조(정보주체와 법정대리인의 권리·의무 및 그 행사방법) ① 정보주체는 주식회사 린허브에 대해 언제든지 개인정보 열람·정정·삭제·처리정지 요구 등의 권리를 행사할 수 있습니다. ② 제1항에 따른 권리 행사는주식회사 린허브에 대해 「개인정보 보호법」 시행령 제41조제1항에 따라 서면, 전자우편, 모사전송(FAX) 등을 통하여 하실 수 있으며 주식회사 린허브는 이에 대해 지체 없이 조치하겠습니다. ③ 제1항에 따른 권리 행사는 정보주체의 법정대리인이나 위임을 받은 자 등 대리인을 통하여 하실 수 있습니다.이 경우 “개인정보 처리 방법에 관한 고시(제2020-7호)” 별지 제11호 서식에 따른 위임장을 제출하셔야 합니다. ④ 개인정보 열람 및 처리정지 요구는 「개인정보 보호법」 제35조 제4항, 제37조 제2항에 의하여 정보주체의 권리가 제한 될 수 있습니다. ⑤ 개인정보의 정정 및 삭제 요구는 다른 법령에서 그 개인정보가 수집 대상으로 명시되어 있는 경우에는 그 삭제를 요구할 수 없습니다. ⑥ 주식회사 린허브는 정보주체 권리에 따른 열람의 요구, 정정·삭제의 요구, 처리정지의 요구 시 열람 등 요구를 한 자가 본인이거나 정당한 대리인인지를 확인합니다. 제6조(처리하는 개인정보의 항목 작성) ① 린허브는 다음의 개인정보 항목을 처리하고 있습니다. 1. 홈페이지 회원가입 및 관리 필수항목 : 이메일, 비밀번호, 로그인ID, 성별, IP 주소, 국가, 언어 선택항목 : 생년월일 (본인인증), 쿠키(로그인 기억) 2. 유료 서비스 이용 필수항목 : 결제 수단에 따른 결제 정보, 성함, 연락처 3. 창작자 회원 포인트 정산 필수항목 : 성함, 생년월일, 환급 계좌 정보, 증빙 서류, 사업자등록 정보 제7조(개인정보의 파기) ① 린허브는 개인정보 보유기간의 경과, 처리목적 달성 등 개인정보가 불필요하게 되었을 때에는 지체없이 해당 개인정보를 파기합니다. ② 정보주체로부터 동의받은 개인정보 보유기간이 경과하거나 처리목적이 달성되었음에도 불구하고 다른 법령에 따라 개인정보를 계속 보존하여야 하는 경우에는, 해당 개인정보를 별도의 데이터베이스(DB)로 옮기거나 보관장소를 달리하여 보존합니다. ③ 개인정보 파기의 절차 및 방법은 다음과 같습니다. 1. 파기절차 린허브는 파기 사유가 발생한 개인정보를 선정하고, 린허브의 개인정보 보호책임자의 승인을 받아 개인정보를 파기합니다. 2. 파기방법 전자적 파일 형태의 정보는 기록을 재생할 수 없는 기술적 방법을 사용합니다 제8조(개인정보의 안전성 확보 조치) 린허브는 개인정보의 안전성 확보를 위해 다음과 같은 조치를 취하고 있습니다. 1. 정기적인 자체 감사 실시 개인정보 취급 관련 안정성 확보를 위해 정기적(분기 1회)으로 자체 감사를 실시하고 있습니다. 2. 개인정보 취급 직원의 최소화 및 교육 개인정보를 취급하는 직원을 지정하고 담당자에 한정시켜 최소화 하여 개인정보를 관리하는 대책을 시행하고 있습니다. 3. 내부관리계획의 수립 및 시행 개인정보의 안전한 처리를 위하여 내부관리계획을 수립하고 시행하고 있습니다. 4. 개인정보의 암호화 이용자의 개인정보는 비밀번호는 암호화 되어 저장 및 관리되고 있어, 본인만이 알 수 있으며 중요한 데이터는 파일 및 전송 데이터를 암호화 하거나 파일 잠금 기능을 사용하는 등의 별도 보안기능을 사용하고 있습니다. 5. 접속기록의 보관 및 위변조 방지 개인정보처리시스템에 접속한 기록을 최소 6개월 이상 보관, 관리하고 있으며, 접속 기록이 위변조 및 도난, 분실되지 않도록 보안기능 사용하고 있습니다. 6. 개인정보에 대한 접근 제한 개인정보를 처리하는 데이터베이스시스템에 대한 접근권한의 부여,변경,말소를 통하여 개인정보에 대한 접근통제를 위하여 필요한 조치를 하고 있으며 침입차단시스템을 이용하여 외부로부터의 무단 접근을 통제하고 있습니다. 7. 비인가자에 대한 출입 통제 개인정보를 보관하고 있는 물리적 보관 장소를 별도로 두고 이에 대해 출입통제 절차를 수립, 운영하고 있습니다. 제9조(개인정보 자동 수집 장치의 설치•운영 및 거부에 관한 사항) ① 린허브는 이용자에게 개별적인 맞춤서비스를 제공하기 위해 이용정보를 저장하고 수시로 불러오는 ‘쿠키(cookie)’를 사용합니다. ② 쿠키는 웹사이트를 운영하는데 이용되는 서버(http)가 이용자의 컴퓨터 브라우저에게 보내는 소량의 정보이며 이용자들의 PC 컴퓨터내의 하드디스크에 저장되기도 합니다. 가. 쿠키의 사용 목적 : 이용자가 방문한 각 서비스와 웹 사이트들에 대한 방문 및 이용형태, 인기 검색어, 보안접속 여부, 등을 파악하여 이용자에게 최적화된 정보 제공을 위해 사용됩니다. 나. 쿠키의 설치•운영 및 거부 : 웹브라우저 상단의 도구>인터넷 옵션>개인정보 메뉴의 옵션 설정을 통해 쿠키 저장을 거부 할 수 있습니다. 다. 쿠키 저장을 거부할 경우 맞춤형 서비스 이용에 어려움이 발생할 수 있습니다. 제10조 (개인정보 보호책임자) ① 주식회사 린허브 은(는) 개인정보 처리에 관한 업무를 총괄해서 책임지고, 개인정보 처리와 관련한 정보주체의 불만처리 및 피해구제 등을 위하여 아래와 같이 개인정보 보호책임자를 지정하고 있습니다. ▶ 개인정보 보호책임자 성명 :양준명 이메일 : [email protected] 제11조(개인정보 열람청구) 정보주체는 「개인정보 보호법」 제35조에 따른 개인정보의 열람 청구를 서비스 홈페이지 1:1 문의를 통하여 할 수 있습니다. 린허브는 정보주체의 개인정보 열람청구가 신속하게 처리되도록 노력하겠습니다. 제12조(권익침해 구제방법) 정보주체는 개인정보침해로 인한 구제를 받기 위하여 개인정보분쟁조정위원회, 한국인터넷진흥원 개인정보침해신고센터 등에 분쟁해결이나 상담 등을 신청할 수 있습니다. 이 밖에 기타 개인정보침해의 신고, 상담에 대하여는 아래의 기관에 문의하시기 바랍니다. 1. 개인정보분쟁조정위원회 : (국번없이) 1833-6972 (www.kopico.go.kr) 2. 개인정보침해신고센터 : (국번없이) 118 (privacy.kisa.or.kr) 3. 대검찰청 : (국번없이) 1301 (www.spo.go.kr) 4. 경찰청 : (국번없이) 182 (cyberbureau.police.go.kr) 「개인정보보호법」제35조(개인정보의 열람), 제36조(개인정보의 정정·삭제), 제37조(개인정보의 처리정지 등)의 규정에 의한 요구에 대 하여 공공기관의 장이 행한 처분 또는 부작위로 인하여 권리 또는 이익의 침해를 받은 자는 행정심판법이 정하는 바에 따라 행정심판을 청구할 수 있습니다. ※ 행정심판에 대해 자세한 사항은 중앙행정심판위원회(www.simpan.go.kr) 홈페이지를 참고하시기 바랍니다. 제13조(개인정보 처리방침 변경) ① 이 개인정보처리방침은 2021년 10월 1부터 적용됩니다.


  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()