<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jinwoo Nam</title>
    <description>Jinwoo Nam's blog</description>
    <link>https://skaws2003.github.io/</link>
    <atom:link href="https://skaws2003.github.io/rss" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 14 Aug 2023 19:35:55 +0900</pubDate>
    <lastBuildDate>Mon, 14 Aug 2023 19:35:55 +0900</lastBuildDate>
    <generator>Jekyll v3.9.3</generator>
    
      <item>
        <title>Leveraging Skill-to-Skill Supervision for Knowledge Tracing</title>
        <description>&lt;h1 id=&quot;leveraging-skill-to-skill-supervision-for-knowledge-tracing&quot;&gt;Leveraging Skill-to-Skill Supervision for Knowledge Tracing&lt;/h1&gt;

&lt;p&gt;(주) 튜링에서 작성하여 AAAI2023 AI4ED 학회에서 발표한 논문입니다 &lt;a href=&quot;https://arxiv.org/abs/2306.06841&quot;&gt;(링크)&lt;/a&gt;. 기존 Knowledge Tracing의 한계를 짚어보고, 이를 해결하는 방법을 논문으로 작성하였습니다.&lt;/p&gt;

&lt;p&gt;만약 Knowledge Tracing이 무엇인지 모르신다면, &lt;a href=&quot;https://medium.com/riiid-teamblog-kr/%EA%B5%90%EC%9C%A1ai%EC%9D%98-%EA%B8%B0%EB%B3%B8%EC%9D%B4%EC%9E%90-%EC%8B%9C%EC%9E%91-deep-knowledge-tracing-dkt-8bc132eda9ec&quot;&gt;Riiid Techblog의 글&lt;/a&gt;을 보고 오시길 추천드립니다.&lt;/p&gt;

&lt;h1 id=&quot;기존의-knowledge-tracing&quot;&gt;기존의 Knowledge Tracing&lt;/h1&gt;

&lt;p&gt;Knowledge Tracing이란, 사용자가 어떤 문제를 풀려고 할 때 사용자가 그 동안 어떤 학습 기록을 가졌는지 살펴보고 사용자가 문제를 맞힐 확률을 예측하는 과제입니다.&lt;/p&gt;

&lt;p&gt;현재 대부분의 Knowledge tracing은 아래와 같은 입·출력 구조를 가집니다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;입력: 사용자가 푼 문제의 리스트, 그 문제를 맞혔는지의 여부, 사용자가 문제를 푼 시각&lt;/li&gt;
  &lt;li&gt;출력: 사용자가 특정 문제를 맞힐 확률&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그런데, 되돌아보면 한 가자 의문이 생깁니다. &lt;strong&gt;현대의 딥 러닝 모델은 왜 하필 이 세 가지만을 사용하고 있는걸까요?&lt;/strong&gt; 사용자의 지식 수준을 추적하는 데 쓰일 수 있는 데이터는 무궁무진하고, 딥 러닝 모델이라면 이러한 데이터를 지식 추적에 활용하는 것도 어렵지 않을텐데 말입니다 &lt;sup&gt;&lt;a href=&quot;#footnote_1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;sup&gt;&lt;a href=&quot;#footnote_2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; &lt;sup&gt;&lt;a href=&quot;#footnote_3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;조사해 보니 답은 간단했습니다. 현재 Knowledge tracing의 주요 benchmark로 사용되고 있는 ASSISTMENT2009 데이터셋이 가진 데이터가 빈약하기 때문입니다.&lt;/p&gt;

&lt;p&gt;특히, ASSISTMENT2009에는 전문가적인 지식이 많이 부족합니다. 전문가가 짜 놓은 단원 간 관계, 전문가가 설정한 난이도 등의 전문가적인 정보는 Knowledge Tracing에 도움이 안 될 수가 없는 정보들이건만, ASSISTMENT2009에는 이러한 정보들이 하나도 없습니다.&lt;/p&gt;

&lt;p&gt;어떤 데이터든 잘 소화해낼 수 있는 딥 러닝 기법이 있고, 또 전문가적 지식이 Knowledge Tracing에 도움이 될 거라는 확신이 있는데도 단지 벤치마크 데이터셋이 이전에 만들어졌다는 이유 하나로 쓸 수 있는 데이터를 못 쓰고 있다는 것은 참 안타까운 일입니다.
그런데 때마침 ASSISTMENT 데이터셋은 수학을 다루고 있고, 제가 근무 중인 (주)튜팅에는 많은 수학 전문가가 계십니다. 그렇다면 이 분들에게 조금만 부탁을 해서 기존의 벤치마크 데이터셋에 새로운 데이터를 보강하면 이런 안타까움을 조금은 해결할 수 있지 않을까요?&lt;/p&gt;

&lt;p&gt;튜링에서 낸 논문, _Leveraging Skill-to-Skill Supervision for Knowledge Tracing_은 이런 생각에서 탄생하게 되었습니다.
Knowledge Tracing 기법들이 새로운 형태의 데이터를 사용할 수 있도록, 이 논문에서는 다음의 세 가지 연구를 수행하였습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;기존의 데이터셋인 ASSISTMENT&lt;sup&gt;&lt;a href=&quot;#footnote_4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;에 단원 간의 관계(Skill-to-Skill Relation)을 더한 ASSISTMENT-SSR 데이터셋을 만들어 공개하였습니다.&lt;/li&gt;
  &lt;li&gt;단원 간 관계 정보를 잘 활용할 수 있는 모델 구조를 제시하였습니다.&lt;/li&gt;
  &lt;li&gt;단원 간 관계 정보 데이터가 Knowledge Tracing에 어떤 효과를 주는 지 분석해 보았습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;assistment-ssr-dataset&quot;&gt;ASSISTMENT-SSR Dataset&lt;/h1&gt;

&lt;p&gt;Knowledge Tracing에 사용될 수 있는 정보는 무궁무진합니다. 그렇기에 그 무궁무진한 정보 중에서 기존 데이터셋에 추가할 정보를 골라내는 것은 중요합니다.&lt;/p&gt;

&lt;p&gt;추가할 정보를 골라내는 작업은 의외로 간단했습니다. 여러 해 동안 교육 업계에 종사한 저도, 사내 수학 전문가분들도 ASSISTMENT 데이터셋에 수학 교육에 있어 가장 중요한 정보 중 하나가 빠져있음에 동의했기 때문입니다. 바로 단원 간 연관관계(Skill-to-Skill Relation)였습니다.&lt;/p&gt;

&lt;p&gt;단원 간 연관관계는 학생의 성취도에 절대적인 영향력을 끼칩니다. 
선행 단원을 학습하지 않은 학생은 그 뒤의 단원을 학습해도 제대로 된 지식을 얻을 수 없고, 반대로 선행 단원을 탄탄히 다져놓은 학생은 다른 학생보다 그 뒤의 단원에서 더 많은 것을 얻어갑니다. 이러한 특성 덕분에, 단원 간 연관관계는 Knowledge Tracing에도 유의미한 기여를 할 것이라 예측하였습니다. 모델이 단원 간 연관관계를 이해하고 연관 단원 학습기록의 유무에 따라 맞힐 확률을 조정할 수 있다면 더 좋은 Knowledge Tracing이 가능할 것이라 생각했기 때문입니다.&lt;/p&gt;

&lt;p&gt;이러한 이유로, 저희 팀은 4명의 사내 수학 전문가에게 부탁하여 기존의 ASSISTMENT-2009 데이터셋이 가지고 있는 110개의 단원 레이블에 단원별 관계를 하나하나 표기하여 주기를 요청하였습니다. 그리고 이것들을 한 데 모아 ASSISTMENT-SSR(&lt;strong&gt;S&lt;/strong&gt;kill-to-&lt;strong&gt;S&lt;/strong&gt;kill &lt;strong&gt;R&lt;/strong&gt;elation) 데이터셋을 만들었습니다.&lt;/p&gt;

&lt;h1 id=&quot;deep-learning-architecture&quot;&gt;Deep Learning Architecture&lt;/h1&gt;
&lt;blockquote&gt;
  &lt;p&gt;자세한 내용은 논문을 참조해 주세요&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/assistment_ssr/model.jpg&quot; alt=&quot;Model Architecture&quot; /&gt;&lt;/p&gt;

&lt;p&gt;단원 간 관계를 담은 데이터셋을 만들었으니 이제 그것을 활용할 수 있는 방법을 고민해 보았습니다.&lt;/p&gt;

&lt;p&gt;위 그림은 단원 간 관계를 활용할 수 있는 딥 러닝 모델 구조의 예시입니다. 모델 구조를 간략하게 설명하면 다음과 같습니다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;단원 간 관계를 그래프로 표현합니다. 그래프의 각 node는 단원, edge는 단원 간 관계성의 유무를 나타냅니다&lt;/li&gt;
  &lt;li&gt;Node2Vec&lt;sup&gt;&lt;a href=&quot;#footnote_5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;을 사용하여 각 node(단원)을 벡터로 표현합니다. 이를 Skill2Vec feature라 합니다.&lt;/li&gt;
  &lt;li&gt;단원 간 관계 외의 기존 ASSISTMENT에 있던 데이터를 사용하여 통상적인 Knowledge Tracing을 수행합니다. 여기에서 나온 loss를 \(L_k\)라 합니다.&lt;/li&gt;
  &lt;li&gt;3.에서 사용한 Embedding을 간단한 Linear layer에 통과시킵니다. 이를 2.에서 만든 Skill2Vec과 비교하여 L2 loss를 구합니다. 이를 \(L_p\)라 합니다.&lt;/li&gt;
  &lt;li&gt;\(L = L_k + L_p\)를 loss함수로 하여 학습합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;단원-간-관계는-knowledge-tracing에서-어떤-역할을-하는가&quot;&gt;단원 간 관계는 Knowledge Tracing에서 어떤 역할을 하는가?&lt;/h1&gt;

&lt;p&gt;제안된 모델과 기존 모델을 비교하며 단원 간 관계가 Knowledge Tracing에 어떤 영향을 끼치는지 확인하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;knowledge-tracing의-정확도-상승&quot;&gt;Knowledge Tracing의 정확도 상승&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Method&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;AUC&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Without Projection Loss&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;80.81&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Random Skill to Skill&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;80.90&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;Expert Guided Skill to SKill&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;81.10&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;위 표의 &lt;strong&gt;Without Projection Loss&lt;/strong&gt;는 제안된 방법을 사용하지 않은 Baseline, &lt;strong&gt;Random Skill to Skill&lt;/strong&gt;은 단원간 관계를 랜덤하게 만든 것, 마지막 &lt;strong&gt;Expert Guided Skill to Skill&lt;/strong&gt;은 전문가가 설정한 단원간 관계도를 사용하여 학습한 모델의 성능입니다.&lt;/p&gt;

&lt;p&gt;위 표의 &lt;strong&gt;Without Projection Loss&lt;/strong&gt;와 &lt;strong&gt;Expert Guided Skill to Skill&lt;/strong&gt;를 비교해 보면, 전문가의 단원 간 관계도를 사용한 쪽의 AUC가 유의미하게 높습니다. 
이는 어떤 방식으로건 단원 간 관계도와 모델 구조가 Knowledge Tracing 성능에 도움이 되었음을 의미합니다.&lt;/p&gt;

&lt;p&gt;이러한 성능 향상이 단순히 모델 구조의 변화에서 온 것인지, 아니면 모델이 진짜로 전문가의 의견을 받아들였기 때문에 생긴 것인지 확인하기 위한 Ablation Study도 진행하였습니다. 
단순히 단원 간 관계를 랜덤하게 만든 &lt;strong&gt;Random Skill-to-Skill&lt;/strong&gt;과 전문가가 만든&lt;strong&gt;Expert Guided Skill to SKill&lt;/strong&gt;을 비교하여 보면, 전문가의 단원 간 관계도를 사용한 쪽이 더 높습니다. 이는 모델이 전문가의 지식을 실제로 활용하고 있으며 ASSISTMENT-SSR에서 추가된 단원 간 관계도가 실제로 Knowledge Tracing에 유용함을 시사합니다.&lt;/p&gt;

&lt;h2 id=&quot;단원-간-관계도는-특히-데이터가-적을-때-더-중요하다&quot;&gt;단원 간 관계도는 특히 데이터가 적을 때 더 중요하다&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/assistment_ssr/auc_difference.jpg&quot; alt=&quot;SSR Role&quot; /&gt;&lt;/p&gt;

&lt;p&gt;교육 관련 서비스를 운영하다 보면 의외로 데이터가 매우 적은 상황을 많이 마주칩니다. 커리큘럼이 바뀌거나, 새로운 문제가 추가되거나 하는 일이 많기 때문입니다.&lt;/p&gt;

&lt;p&gt;일반적으로, AI는 데이터가 쌓여야 일을 잘 할 수 있는 반면 전문가의 지식은 딱히 학생들의 학습 데이터를 필요로 하지 않습니다.
그렇다면, 데이터의 양에 영향을 받지 않는 전문가의 지식은 AI를 학습할 데이터가 적을 때 더 유용하다고 말할 수 있지 않을까요?&lt;/p&gt;

&lt;p&gt;이 가설을 검증해보기 위해 ASSISTMENT-2009 데이터셋에서 5%, 10%, 50%의 학생 정보만 사용해 모델을 학습해 보았습니다.
그 결과는 위의 그래프와 같습니다.&lt;/p&gt;

&lt;p&gt;위의 그래프에서, 빨간 선은 단원간 관계도를 사용한 모델의 AUC, 검은 선은 사용하지 않은 모델의 AUC를 나타냅니다. 그리고 파란 점선은 그 둘의 AUC 차이를 나타냅니다.&lt;/p&gt;

&lt;p&gt;그래프에서 보이다시피, 학습 데이터셋의 크기가 50%, 10%, 5%로 줄수록 단원 간 관계도를 사용한 모델과 사용하지 않은 모델의 성능 차이가 벌어집니다.
데이터 크기에 상관 없는 전문가의 지식이 실제로 데이터가 적을 때 더 좋은 효과를 보이는 것입니다.&lt;/p&gt;

&lt;h1 id=&quot;요약&quot;&gt;요약&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Knowledge Tracing에 사용할 수 있는 정보는 무궁무진합니다. 그런데 지금까지의 AI 모델은 세 가지 데이터만 쓰고 있었습니다.
    &lt;ul&gt;
      &lt;li&gt;이것은 기존의 데이터셋(ASSISTMENT2009)에서 제공하는 데이터 종류가 부족하기 때문입니다.&lt;/li&gt;
      &lt;li&gt;특히, ASSISTMENT2009에는 단원 간 관계도와 같은 전문가적 지식이 부족해 이러한 지식이 오랫동안 외면받았습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Knowledge Tracing이 전문가의 지식을 활용하게 하기 위해 기존의 데이터셋인 ASSISTMENT&lt;sup&gt;&lt;a href=&quot;#footnote_4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;에 단원 간의 관계(Skill-to-Skill Relation)을 더한 ASSISTMENT-SSR 데이터셋을 만들어 공개하였습니다.&lt;/li&gt;
  &lt;li&gt;단원 간 관계 정보를 잘 활용할 수 있는 모델 구조의 예시를 제공하였습니다.&lt;/li&gt;
  &lt;li&gt;ASSISTMENT2009와 ASSISTMENT2009-SSR에 학습된 모델을 비교하여 단원 간 관계 정보가 Knowledge Tracing에 도움이 됨을 밝혔습니다.&lt;/li&gt;
  &lt;li&gt;단원간 관계와 같은 전문가적 정보는 데이터셋의 크기에 무관합니다. 이 때문에 데이터셋의 크기가 작을수록 전문가적 정보가 유용함을 보였습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;a name=&quot;footnote_1&quot;&gt;1&lt;/a&gt;: Piech, Chris et al. “Deep Knowledge Tracing.” NIPS, 2015&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;footnote_2&quot;&gt;2&lt;/a&gt;: Shin, Dongmin et al. “SAINT+: Integrating Temporal Features for EdNet Correctness Prediction.” LAK21, 2020&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;footnote_3&quot;&gt;3&lt;/a&gt;: Ghosh, Aritra and Heffernan, Neil and Lan, Andrew S, “Context-Aware Attentive Knowledge Tracing”, KDD, 2020&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;footnote_4&quot;&gt;4&lt;/a&gt;: https://sites.google.com/site/assistmentsdata/&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;footnote_5&quot;&gt;5&lt;/a&gt;: Grover, Aditya and Jure Leskovec. “node2vec: Scalable Feature Learning for Networks.” KDD, 2016&lt;/p&gt;
</description>
        <pubDate>Mon, 12 Jun 2023 13:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2023/06/12/levergind-s2s/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2023/06/12/levergind-s2s/</guid>
        
        <category>Knowledge Tracing</category>
        
        
      </item>
    
      <item>
        <title>Context-Aware Attentive Knowledge Tracing</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Knowledge Tracing과 그를 위한 Attention mechanism에 대한 지식이 없으시다면, 아래의 Riiid Teamblog 글을 읽고 오시길 추천합니다:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://medium.com/riiid-teamblog-kr/%EA%B5%90%EC%9C%A1ai%EC%9D%98-%EA%B8%B0%EB%B3%B8%EC%9D%B4%EC%9E%90-%EC%8B%9C%EC%9E%91-deep-knowledge-tracing-dkt-8bc132eda9ec&quot;&gt;Deep Knowledge Tracing&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://medium.com/riiid-teamblog-kr/knowledge-tracing%EC%9D%84-%EC%9C%84%ED%95%9C-attention-mechanism-e3451ce13930&quot;&gt;Attention Mechanism for Knowledge Tracing&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;문제-제기&quot;&gt;문제 제기&lt;/h1&gt;

&lt;p&gt;먼저 AKT는 기존의 논문들(특히, DKT 계열: SAKT, DKVMN등)이 제대로 반영하지 못한 세 가지 학습 특성을 지적하고 있습니다&lt;/p&gt;

&lt;h2 id=&quot;1-concept도-중요하지만-개별-problem간의-차이도-중요하다&quot;&gt;1. Concept도 중요하지만, 개별 Problem간의 차이도 중요하다.&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;원문: questions labeled as covering the same concept are closely related but have important individual differences that should not be ignored.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/akt/concept-problem.jpg&quot; alt=&quot;concepts and problems&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림과 같이, 같은 concept에 속한 problem들은 대략적으로 비슷한 성질을 가지고 있습니다. 그러나, 각 문제마다의 차이도 분명히 존재합니다.&lt;/p&gt;

&lt;p&gt;현재 Deep KT 모델의 대부분은 문제 개별의 차이를 무시하고 그 문제가 속한 Concept(skill) 정보만을 활용하고 있습니다. 
그림의 learning sequence에서 아랫쪽 \(&amp;lt; C_1,C_2,C_1,C_1, ...&amp;gt;\)처럼 문제 각각의 특성이 반영되지 않은 input만을 사용하고 있는 것입니다.&lt;/p&gt;

&lt;p&gt;기존 모델이 이렇게 된 이유는 크게 두 가지가 있습니다.&lt;/p&gt;

&lt;p&gt;첫 번째로, Problem의 갯수 \(Q\)의 크기가 Concept의 갯수 \(C\)보다 매우 크기 때문에(\(Q &amp;gt;&amp;gt; C\)) 각각의 문제 모두를 Embedding하면 Embedding 크기만 \(Q·D\) (\(D=(embedding\_dim)\))가 되어 메모리 효율이 극도록 하락하기 때문이고,&lt;/p&gt;

&lt;p&gt;두 번째로, 각 concept은 그 concept을 학습한 사람이 많아 학습하기에 데이터가 충분하지만, 각 Problem을 학습한 인원은 그보다 훨씬 적어 Data Sparsity 문제가 발생하기 때문입니다.&lt;/p&gt;

&lt;h2 id=&quot;2-같은-문제를-보더라도-사람마다-받아들이는-방식이-다르다&quot;&gt;2. 같은 문제를 보더라도 사람마다 받아들이는 방식이 다르다&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;원문: the way a learner comprehends and learns while responding to a question depends on the learner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;당연하지만, 모든 학생은 자신의 경험을 토대로 당면한 문제를 풀고, 또 정보를 받아들입니다.
다시 말해, 같은 문제라도 각각의 학생마다 받아들이는 방식(&lt;em&gt;i.e. embedding vector&lt;/em&gt;)가 달라질 수 있다는 것입니다.&lt;/p&gt;

&lt;p&gt;그러나 현재의 Deep KT관련 모델은 이러한 사실을 잘 반영하지 않은 채, 단순히 각 concept마다의 embedding을 사용하고 있으므로, 학생 각각의 특성을 잘 반영하지 못한다고 할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;3-오래-전에-푼-문제는-잊혀지고-현재-풀고-있는-문제과-관련-없는-지식은-사용되지-않는다&quot;&gt;3. 오래 전에 푼 문제는 잊혀지고, 현재 풀고 있는 문제과 관련 없는 지식은 사용되지 않는다&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;원문: when a learner faces a new question, past experiences i) on unrelated concepts and ii) that are from too long ago are not likely to be highly relevant.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;예를 들어, 어떤 모델 \(M\)이 학생 \(S\)가 어떤 문제 \(q_t\)를 풀 수 있을 지 예측하기 위해 앞의 200문제 (\(q_{t-200}, ... , q_{t-1}\))를 살펴본다고 합시다.
현재 대부분의 Attention 기반 Deep KT 모델은 여기서 \(q_{t-200}\)과 \(q_{t-1}\)을 동등하게 사용하고 있습니다.
그러나 이것은 학생이 이전에 푼 문제를 점점 잊는다는 사실을 무시한 것입니다. 학생이 \(q_{t-200}\)에 관해 기억하고 있는 정보의 양과 \(q_{t-1}\)에 관해 기억하고 있는 정보의 양은 다를 수밖에 없고, 이러한 사실이 모델에 반영되면 좋은 효과를 기대할 수 있을 것입니다.&lt;/p&gt;

&lt;p&gt;또 하나, 학생이 “Venn Diagram” Concept을 학습하다가, 잠시 “Prime Number”에 관한 숙제를 하고, 다시 “Venn Diagram”을 학습하게 되었다고 가정해 봅시다.
이 경우, 학생이 최근에 풀었던 “Prime Number” 정보보다는 그 전에 학습했던 “Venn Diagram”관련 문제 정보가 훨씬 중요할 것입니다.
이런 식의 concept switching은 생각보다 자주 일어나는 일이지만, 아직까지 이를 명시적으로 고려한 모델은 없습니다.&lt;/p&gt;

&lt;h1 id=&quot;contribution&quot;&gt;Contribution&lt;/h1&gt;

&lt;p&gt;AKT에서는 위에서 주장한 주요 문제점을 해결하기 위해 다음의 세 가지 contribution을 만들었다고 주장합니다:&lt;/p&gt;

&lt;h2 id=&quot;1-rasch-model-based-embeddings&quot;&gt;1. Rasch Model-Based Embeddings&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;“Concept도 중요하지만, 개별 Problem간의 차이도 중요하다.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rasch model에서 영감을 받아, AKT는 Problem 각각의 차이를 반영하면서도 메모리 사용량과 Data Sparsity 문제를 효과적으로 해결할 수 있는 Problem Embedding 기법을 도입하였습니다.&lt;/p&gt;

&lt;p&gt;먼저, timestamp \(t\)에서 question \(q_t\) of concept \(c_t\)의 embedding \(x_t\)는 다음과 같이 정의됩니다:&lt;/p&gt;

\[\textbf{x}_t = \textbf{c}_{c_t} + \mu _{q_t} · \textbf{d}_{c_t}\]

&lt;p&gt;여기에서 \(\textbf{c}_{c_t} \in \mathbb{R}^D\)는 \(c_t\)의 base embedding, \(\mu _{q_t} \in \mathbb{R}^1\)는 \(c_t\) 내에서의 \(q_t\)의 난이도를 나타낸 하나의 숫자, \(\textbf{d}_{c_t} \in \mathbb{R}\)는 개별 Problem의 난이도에 따른 embedding varition을 나타내는 벡터입니다.&lt;/p&gt;

&lt;p&gt;이러한 방식으로 임베딩을 할 경우, 앞서 언급했더 Problem을 Embedding하는 것이 어려운 이유 두 가지를 효과적으로 회피할 수 있습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;메모리 부족 문제&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Problem의 갯수를 \(Q\), Concept의 갯수를 \(C\), 각 Embedding의 Dimension을 \(D\)라고 했을 때, 단순히 Problem각각을 Embedding하면 \(QD\)의 메모리가 소모됩니다.
하지만 위 방식은 \(2CD+Q\) (\(CD\) for \(\textbf{c}, \textbf{d}\), \(Q\) for \(\mu\))만큼 메모리를 소모하므로, \(Q &amp;gt;&amp;gt; C\)임을 감안하면 메모리가 크게 절약됩니다.&lt;/p&gt;

&lt;p&gt;비슷하게, 학생이 어떤 문제 \(q_t\) 를 맞히거나 틀렸을 때(\(r_t\)) 얻는 정보를 나타내는 벡터 \(y_t\)(knowledge embedding)은 다음과 같이 정의됩니다:&lt;/p&gt;

\[\textbf{y}_t = \textbf{e}_{c_t,r_t} + \mu _{q_t} · \textbf{f}_{c_t,r_t}\]

\[\textbf{e}_{c_t,r_t} = \textbf{c}_{c_t} + \textbf{g}_{r_t}\]

&lt;p&gt;위와 마찬가지로, \(\textbf{e}_{c_t,r_t} \in \mathbb{R}^D\), \(\textbf{f}_{c_t,r_t} \in \mathbb{R}^D\)는 각각 base knowledge embedding, Problem 난이도에 따른 embedding variation을 나타냅니다.&lt;/p&gt;

&lt;p&gt;추가적으로, knowledge embedding에서는 메모리 효율을 위해 \(\textbf{e}_{c_t,r_t}\)를 앞에서 구한 \(\textbf{c}_{c_t}\)를 이용해 재정의하였습니다.
위의 식에서, \(r_t \in \{0,1\}\)이므로, \(\textbf{g}_{r_t}\)는 \(2D\)만의 메모리(negligible)를 소모합니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Data Sparsity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Problem 개별의 Embedding이라고는 해도, 기본적으로 concept embedding \(c_{c_t}\)에서 출발하기 때문에 Problem embedding을 처음부터 학습하는 것보다 훨씬 효율적입니다.&lt;/p&gt;

&lt;h2 id=&quot;2-context-aware-representations-of-question-and-knowledge&quot;&gt;2. Context-aware Representations of question and knowledge&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;같은 문제를 보더라도 사람마다 받아들이는 방식이 다르다&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;각각의 problem embedding과 knowledge embedding이, 학생이 이전에 풀었던 problem에 영향을 받도록 하여 학생 개개인에 맞춘 embedding을 생성하였습니다.
다시 말해, 학생 개인에 맞춘 problem embedding \(\textbf{x}\prime_{t} = \textit{f}_{enc} (\textbf{x}_1, \textbf{x}_2, ..., \textbf{x}_t)\)로 정의하였습니다. 
여기에서, AKT는 \(f_{enc_x}\)로 self-attention mechanism을 사용하였습니다.&lt;/p&gt;

&lt;p&gt;추가로, knowledge embedding, \(\textbf{y}_t\)에 대해서도 같은 작업을 진행하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;3-monotonic-attention-mechanism&quot;&gt;3. monotonic attention mechanism&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;오래 전에 푼 문제는 잊혀지고, 현재 풀고 있는 문제과 관련 없는 지식은 사용되지 않는다&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;기존의 attention에서 attention weight \(\alpha_{t,\tau}\)는 다음과 같이 정의됩니다:&lt;/p&gt;

\[\alpha_{t,\tau} = Softmax(\frac{\textbf{q}_t^T \textbf{k}_\tau}{\sqrt{D_k}})\]

&lt;p&gt;monotonic attention에서는 attention weight가 다음과 같이 정의됩니다:&lt;/p&gt;

\[s_{t,\tau} = Softmax(\frac{exp(-\theta · d(t,\tau)) · \textbf{q}_t^T \textbf{k}_\tau}{\sqrt{D_k}})\]

&lt;p&gt;\(\theta &amp;gt; 0\)는 learnable decay parameter, \(d(t,\tau)\)는 각 timestamp \(t,\tau\)간의 거리 함수입니다.&lt;/p&gt;

&lt;p&gt;여기서 두 timestamp간의 거리 함수 \(d(t,\tau)\)는 1) 오래 전에 푼 문제를 잊는 것과 2) 현재 풀고 있는 문제와 관련 있는 지식만 골라내는 역할을 합니다.&lt;/p&gt;

&lt;p&gt;거리 함수는 다음과 같이 구성되어 있으며:&lt;/p&gt;

\[d(t,\tau) = |t-\tau|·\sum_{t'=\tau+1}^{t} f_{attention}(t,t')\]

&lt;p&gt;여기서 앞의 \(t-\tau\) 는 오래 된 지식을 잊게 하는 역할을 하고, 뒤의 \(\sum_{t'=\tau+1}^{t} f_{attn}(t,t')\)는 attention weight를 통해 문제와 관련 없는 지식을 걸러내는 역할을 합니다.&lt;/p&gt;

&lt;h1 id=&quot;모델-구조&quot;&gt;모델 구조&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/akt/akt_overall.jpg&quot; alt=&quot;overall AKT architecture&quot; /&gt;&lt;/p&gt;

&lt;p&gt;최종적인 모델 구조는 위 그림과 같습니다.
Input sequence가 들어오면,&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;먼저 Rasch model-based embedding을 만들고,&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Attention 기반의 question encoder와 knowledge encoder로 context-aware representation을 만들고,&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;생성된 Context-aware embedding을 이용하여 예측을 수행합니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2.와 3.에 사용되는 모든 attention은 motonic attention mechanism을 사용합니다.&lt;/p&gt;

&lt;h1 id=&quot;구현&quot;&gt;구현&lt;/h1&gt;
&lt;h2 id=&quot;구현-과정&quot;&gt;구현 과정&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;논문을 보고 대략적으로 모델 구현&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;official repo를 참고하여 각종 parameter값을 넣고, 실수한 부분이나 논문과 코드가 다른 부분을 대략적으로 수정 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;models/akt.py&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseAKTEstimator&lt;/code&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;official repo를 참고하여 코드 한두 줄로 끝나지 않을 만한 큰 변화들을 반영 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;models/originalakt.py&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OriginalAKTEstimator&lt;/code&gt;)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;데이터셋의 경우, 원활한 비교를 위해 official code와 최대한 똑같은 데이터를 내도록 하였습니다. 예를 들어 데이터를 length=200으로 자르는 과정에서 자르는 위치를 달리하여 data augmentation을 할 수도 있으나, official code가 그러고 있지 않은 것으로 보이므로 data augmentation을 하지 않았습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;구현-결과&quot;&gt;구현 결과&lt;/h2&gt;

&lt;h3 id=&quot;training-curve&quot;&gt;Training Curve&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;training auc
&lt;img src=&quot;/files/images/akt/trainauc.jpg&quot; alt=&quot;train auc&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;validation auc
&lt;img src=&quot;/files/images/akt/validauc.jpg&quot; alt=&quot;valid auc&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;최종-결과&quot;&gt;최종 결과&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mean AUC on 5 folds: 0.7987
mean accuracy on 5 folds: 76.01%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;why-lower&quot;&gt;why lower?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;motonic attention의 경우, official coda와 이 프로젝트의 output이 거의 같음을 확인함 (cuda version 차이 등에서 오는 작은 변화 제외)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decay_rate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;attended_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;monotonic_attention&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위와 같은 input(akt.py,L727)을 이 프로젝트 attention에 넣었을 때,&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attended_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# = 1.9523
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attended_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# tensor([ 1.8664, -0.5779, -0.0891, -2.5754,  0.6524,  1.7813,  2.0745,  0.9368,
#          0.2846,  0.6477,  3.7393,  0.8715,  1.2119,  0.4349, -1.8076,  2.2776,
#          1.4826,  1.8024,  2.4675,  3.2923,  1.6706, -2.1705, -0.6615,  0.5187,
#          0.6413,  2.2926, -0.5753,  5.9830,  1.8191, -0.1177,  1.3508,  2.1476],
#       device='cuda:0', grad_fn=&amp;lt;SelectBackward0&amp;gt;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위와 같은 결과가 나옴.&lt;/p&gt;

&lt;p&gt;AKT official code의 경우,&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gammas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attention&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero_pad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gammas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위 코드로 테스트하였음(akt.py). 결과는,&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# = 1.9521
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attended_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# tensor([ 1.8664, -0.5780, -0.0891, -2.5754,  0.6524,  1.7813,  2.0745,  0.9368,
#         0.2846,  0.6477,  3.7393,  0.8715,  1.2119,  0.4348, -1.8076,  2.2776,
#         1.4826,  1.8024,  2.4675,  3.2923,  1.6706, -2.1706, -0.6615,  0.5187,
#         0.6413,  2.2926, -0.5753,  5.9830,  1.8190, -0.1177,  1.3508,  2.1475],
#       device='cuda:0', grad_fn=&amp;lt;SelectBackward&amp;gt;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위와 같음.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;위의 결과로 볼 때, gpu arch의 차이나 pytorch version up에 따른 차이가 있을 수 있음&lt;/li&gt;
  &lt;li&gt;논문에서 나오지 않아 구현되지 않았거나, 차이가 나는 부분이 조금 더 존재하는 것으로 보임&lt;/li&gt;
  &lt;li&gt;fold 1에서 official code를 돌렸을 때, seed 값을 디폴트에서 바꾸면(seed=772) auc=0.819 수준의 결과가 나옴을 확인함. 이것도 영향이 있을 것으로 보임&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;roc-curve&quot;&gt;ROC Curve&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/files/images/akt/roc.png&quot; alt=&quot;ROC Curve&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;

&lt;h2 id=&quot;의문스러웠던-것들&quot;&gt;의문스러웠던 것들&lt;/h2&gt;
&lt;p&gt;저자인 Aritra Ghosh가 공개한 &lt;a href=&quot;https://github.com/arghosh/AKT&quot;&gt;official code&lt;/a&gt;를 살펴본 결과, 실제 코드가 논문과 다르게 구현되었거나, 혹은 논문에 설명되지 않은 것이 코드에는 들어 있는 경우가 많았습니다. 또, official code의 구현 중 의문스러운 것들도 있었습니다.&lt;/p&gt;

&lt;p&gt;아래는 그것들 중 기억나는 것을 모아 본 것입니다&lt;/p&gt;

&lt;h3 id=&quot;k-fold-cross-validation&quot;&gt;K-Fold Cross validation&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/akt/kfoldoriginal.jpg&quot; alt=&quot;original k-fold cross validation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 그림과 같이, 일반적으로 K-Fold cross validation은 &lt;strong&gt;먼저 TEST set을 따로 빼 놓고 나머지를 K등분&lt;/strong&gt; 하여 train/valid로 사용, 최종적으로 학습된 5개의 모델을 종합하여 Test 결과를 얻는 방식을 말합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/akt/kfoldakt.jpg&quot; alt=&quot;AKT k-fold cross validation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그러나 이 논문에서 사용한 방법은 조금 다릅니다. 위 그림과 같이, 여기서는 &lt;strong&gt;전체 데이터를 K등분&lt;/strong&gt; 한 뒤 train/valid/test를 돌려 가며 테스트하고 있습니다.
이렇게 할 경우, 생성된 5개의 모델 중 누군가는 다른 모델의 Test set을 학습하게 되므로, 5개의 모델을 종합하여 쓸 수도 없게 됩니다.&lt;/p&gt;

&lt;h3 id=&quot;attention&quot;&gt;Attention&lt;/h3&gt;
&lt;p&gt;AKT에서는 Attention mechanism이 상당히 광범위하게 사용됩니다. Context-Aware Feature Encoding의 &lt;em&gt;Question Encoder&lt;/em&gt;, &lt;em&gt;Knowledge Encoder&lt;/em&gt; 두 부분에서는 Self-attention을 사용하고 있고, &lt;em&gt;Knowledge Retriever&lt;/em&gt; 에서는 Question embedding, knowledge embedding 둘을 섞는데 Attention Mechanism을 이용하고 있습니다.&lt;/p&gt;

&lt;p&gt;Attention mechanism에서, query, key, value가 들어오면 이들 각각에 linear layer를 적용합니다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k_linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q_linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v_linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attention&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그러나, 실제 구현된 코드를 보면 AKT에 사용된 Attention이 일반적인 Attention과는 조금 다른 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k_linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k_linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# self.k_linear applied on q
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v_linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attention&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(본래 코드는 이것과 약간 다르나, 항상 “True”인 한 parameter를 제외하면 위와 같아집니다)&lt;/p&gt;

&lt;p&gt;일반적으로 Attention은 input key와 query가 같더라도 이들에게 적용되는 linear layer가 다르나, 여기서는 둘을 똑같은 것으로 사용합니다.&lt;/p&gt;

&lt;h3 id=&quot;rasch-model-based-embeddings&quot;&gt;Rasch Model-Based Embeddings&lt;/h3&gt;
&lt;p&gt;위에서, 학생이 어떤 문제 \(q_t\) 를 맞히거나 틀렸을 때(\(r_t\)) 얻는 정보를 나타내는 벡터 \(y_t\)(knowledge embedding)은 다음과 같이 정의된다고 하였습니다:&lt;/p&gt;

\[\textbf{y}_t = \textbf{e}_{c_t,r_t} + \mu _{q_t} · \textbf{f}_{c_t,r_t}\]

\[\textbf{e}_{c_t,r_t} = \textbf{c}_{c_t} + \textbf{g}_{r_t}\]

&lt;p&gt;그러나 실제로 코드를 보면 \(\textbf{f}_{c_t,r_t}\) 또한 이와 같은 방식의 embedding을 사용하고 있었습니다:&lt;/p&gt;

\[\textbf{f}_{c_t,r_t} = \textbf{d}_{c_t} + \textbf{h}_{r_t}a\]

&lt;p&gt;논문의 context상 이해가 되지 않는 선택은 아니나, 한 줄이라도 써 주었으면 어떨까 합니다.&lt;/p&gt;

&lt;h3 id=&quot;monotonic-attention&quot;&gt;Monotonic Attention&lt;/h3&gt;

&lt;p&gt;monotonic attention에서 attention weight를 구하는 식은 다음과 같았습니다:&lt;/p&gt;

\[s_{t,\tau} = Softmax(\frac{exp(-\theta · d(t,\tau)) · \textbf{q}_t^T \textbf{k}_\tau}{\sqrt{D_k}})\]

&lt;p&gt;그러나, 실제로는 다음과 같이 구해지고 있었습니다:&lt;/p&gt;

\[s_{t,\tau} = Softmax(\frac{exp(-\theta · \sqrt{d(t,\tau)}) · \textbf{q}_t^T \textbf{k}_\tau}{\sqrt{D_k}})\]

&lt;hr /&gt;
&lt;p&gt;References&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ghosh, Aritra and Heffernan, Neil and Lan, Andrew S, “Context-Aware Attentive Knowledge Tracing”, In KDD, 2020.&lt;/li&gt;
  &lt;li&gt;Ghosh’s official AKT code: https://github.com/arghosh/AKT&lt;/li&gt;
  &lt;li&gt;Riiid Teamblog, “학습 시점과 문항 유사도를 고려한 Knowledge Tracing 모델”: https://medium.com/riiid-teamblog-kr/%ED%95%99%EC%8A%B5-%EC%8B%9C%EC%A0%90%EA%B3%BC-%EB%AC%B8%ED%95%AD-%EC%9C%A0%EC%82%AC%EB%8F%84%EB%A5%BC-%EA%B3%A0%EB%A0%A4%ED%95%9C-knowledge-tracing-%EB%AA%A8%EB%8D%B8-5192a3e28f46&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 11 Jan 2023 13:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2023/01/11/AKT/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2023/01/11/AKT/</guid>
        
        <category>Knowledge Tracing</category>
        
        
      </item>
    
      <item>
        <title>Unsupervised Natural Language Video Localization</title>
        <description>&lt;h1 id=&quot;project-description&quot;&gt;Project Description&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;ICCV 2021 Accepted as Oral Paper!! 자세한 내용을 추후 업데이트 하겠습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;NC소프트에서 지원받아 변리사님과 함께 국내 특허를 출원하였습니다. (출원번호 10-2021-0076124)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/nlvl/nlvl.gif&quot; alt=&quot;Natural Language Video Localization&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Natural Language Video Localization (NLVL)은 위의 영상과 같이 비디오와 자연어 쿼리가 주어졌을 때 비디오에서 쿼리가 가리키는 부분을 찾아내는 문제입니다.
&lt;a href=&quot;https://skaws2003.github.io/2020/09/09/NLVL/&quot;&gt;앞선 포스트&lt;/a&gt;에서는 이 문제를 Fully-supervised learning을 통해 해결하였습니다. 그러나 이러한 접근법은 필연적으로 엄청난 양의 데이터를 모아야 한다는 단점이 있습니다. 
특히, NLVL을 위해서는 (비디오, 자연어 쿼리, 쿼리가 가리키는 영역)의 삼중쌍을 모아야 하나, 이러한 형태의 데이터는 annotation cost가 너무 높아 쉽게 만들 수 없습니다.&lt;/p&gt;

&lt;p&gt;여기서는 NLVL의 annotation cost 문제를 해결하기 위해 Unsupervised Natural Language Video Localization (uNLVL)문제를 제안하고 이를 해결하는 한 가지 방법을 제시하였습니다.
uNLVL은 더 이상 모델 학습을 위해 (비디오, 자연어 쿼리, 쿼리가 가리키는 영역)와 같은 paired data를 필요로 하지 않으며, 오로지 주제와 관련된 비디오 집합, 적당히 큰 자연어 말뭉치, 그리고 미리 학습된 객체 검출기(pre-trained object detector)의 세 가지 unpaired data만으로 NLVL 모델을 학습할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;결과&quot;&gt;결과&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/nlvl/metrics.jpg&quot; alt=&quot;Evaluation metrics&quot; /&gt;&lt;/p&gt;

&lt;p&gt;제안된 방법의 성능을 측정하기 위해, 여기서는 R@{0.3, 0.5, 0.7}와 mIoU의 총 네 가지 척도를 사용하였습니다. 위의 그림과 같이, R@{0.3, 0.5, 0.7}는 모델이 예측한 구간과 Ground Truth 구간의 IoU(Intersection over Union)이 각각 {0.3, 0.5, 0.5}를 넘는 예측의 분율을 의미하여, mIoU는 모델 예측과 GT의 mean IoU 입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/nlvl/unlvl-results.png&quot; alt=&quot;Performance Comparison&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 표는 이 프로젝트를 통해 제안된 모델의 성능을 다른 환경(fully-supervised, weakly-supervised)에서 학습된 모델과 비교한 것입니다. 여기에서 제안된 모델(UnVLoC)은 weakly-supervised learning 기반 모델이나 일부 fully-supervised learning 모델보다 크게 높은 성능을 보여주고 있습니다. Unpaired data collection만으로 annotation cost가 큰 paired data를 이용하여 학습된 모델보다 더 높은 NLVL 성능을 얻어낸 것입니다.&lt;/p&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;이번 연구는 아이디어 구상부터 논문 작성까지 한 팀의 리더로서 활동하였습니다.
    &lt;ul&gt;
      &lt;li&gt;혼자 연구한 경험이야 이전에도 있었지만 팀의 리더로 활동하는 것은 그것과 완전히 다른 경험이었습니다.&lt;/li&gt;
      &lt;li&gt;하루종일 같이 있는 팀원과 시도때도 없이 의견을 교환하고 차이를 조정하는 일이 쉽지많은 않았습니다. 그러나 다행히도 서로 상처 주거나 하는 일 없이 원만하게 일을 끝마칠 수 있었습니다.&lt;/li&gt;
      &lt;li&gt;해야 하는 작업을 팀원에게 분배하는 것도 쉬운 일은 아니었습니다. 그러나 시간이 지나면서 작업을 적절히 배분하게 되었습니다.
        &lt;ul&gt;
          &lt;li&gt;팀원이 어떤 작업을 좋아하는 지를 잘 파악하여 선호대로 배분하고, 모두가 기피하는 작업은 최대한 돌아가면서 처리했습니다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;프로젝트를 논문으로 만드는 과정에서 논문이 써지는 프로세스를 배웠습니다.
    &lt;ul&gt;
      &lt;li&gt;제가 주도한 연구가 논문이 될 뻔한 적은 이전에도 몇 있었으나, 실제로 인정을 받아 논문 제출까지 제 손으로 끝마친 것은 이 연구가 처음이었습니다.&lt;/li&gt;
      &lt;li&gt;일찌감치 글쓰기를 끝내 놓고 끊임없이 표현을 clear하게 바꾸거나 어조를 defensive하게 바꾸는 작업을 하였습니다. 고된 과정이었고 교수님께 지적도 많이 받았으나 이 과정에서 실용적인 논문 글쓰기를 배울 수 있었습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;
&lt;p&gt;[1] Jiyang Gao, Chen Sun, Zhenheng Yang, and Ram Nevatia. “Tall: Temporal activity localization via language query”. In ICCV, 2017.&lt;br /&gt;
[2] Jonghwan Mun, Minsu Cho, and Bohyung Han. “Local-Global Video-Text Interactions for Temporal Grounding”. In CVPR, 2020.&lt;br /&gt;
[3] Niluthpol Chowdhury Mithun, Sujoy Paul, and Amit K Roy-Chowdhury. “Weakly supervised video moment retrieval from text queries”. In CVPR, 2019.&lt;br /&gt;
[4] Zhenfang Chen, Lin Ma, Wenhan Luo, Peng Tang, and Kwan-Yee K. Wong. “Look closer to ground better: Weakly supervised temporal grounding of sentence in video”. ArXiv, abs/2001.09308, 2020.&lt;br /&gt;
[5] Zhijie Lin, Zhou Zhao, Zhu Zhang, Qi Wang, and Huasheng Liu. “Weakly-supervised video moment retrieval via semantic completion network”. In AAAI, 2020.&lt;/p&gt;
</description>
        <pubDate>Sun, 10 Jan 2021 22:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2021/01/10/uNLVL/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2021/01/10/uNLVL/</guid>
        
        <category>Vision and Language</category>
        
        
      </item>
    
      <item>
        <title>Natural Language Video Localization</title>
        <description>&lt;h1 id=&quot;project-description&quot;&gt;Project Description&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/nlvl/nlvl.gif&quot; alt=&quot;Natural Language Video Localization&quot; /&gt;&lt;/p&gt;

&lt;p&gt;NC소프트로부터 좋은 기회를 얻어 진행하게 된 프로젝트입니다.&lt;/p&gt;

&lt;p&gt;Natural Language Video Localization (NLVL)은 위의 영상과 같이 비디오와 자연어 쿼리가 주어졌을 때 비디오에서 쿼리가 가리키는 부분을 찾아내는 문제입니다. 다시 말해, 문제의 Input과 Output은 다음과 같습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Input
    &lt;ul&gt;
      &lt;li&gt;랜덤한 길이의 비디오&lt;/li&gt;
      &lt;li&gt;비디오의 한 부분을 가리키는 자연어 문장 (e.g. “A person is sitting at a table eating a sandwich”)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Output
    &lt;ul&gt;
      &lt;li&gt;비디오에서 자연어가 가리키는 구간 정보 (e.g. “8s~13s”)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;프로젝트-목표&quot;&gt;프로젝트 목표&lt;/h1&gt;

&lt;p&gt;프로젝트는 NLVL을 위해 개발된 DiDeMo[1] 데이터셋에서 Stat-of-the-art 성능을 달성하는 것을 목표로 진행되었습니다. 이를 위해, 다음과 같은 세부 목표가 세워졌습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;당시 가장 높은 성능을 보였던 ASST[2]를 재구현하고 성능 재현(Reproduce)&lt;/li&gt;
  &lt;li&gt;재구현된 것을 개량하여 성능을 높임&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;개선-사항&quot;&gt;개선 사항&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;프로젝트 규정상 자세한 내용을 공개할 수 없는 점 양해 부탁드립니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;multi-stream-learning&quot;&gt;Multi-Stream Learning&lt;/h2&gt;

&lt;p&gt;일반적으로 비디오를 다룰 때는 아래의 두 가지의 Feature를 사용합니다. 아래에서 L은 비디오의 길이, m과 n은 피쳐의 차원입니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;각 프레임을 Resnet 등으로 인코딩한 RGB Feature (L*m)&lt;/li&gt;
  &lt;li&gt;두 프레임 사이의 optical flow를 사용한 Flow Feature (L*n)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;저는 위의 두 가지 Feature에 더해, 추가로 2가지의 Feature를 더 만들어서 모델에 잇풋으로 주었습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Image Captioning Feature
    &lt;ul&gt;
      &lt;li&gt;프레임마다 Image Captioning을 하고, 이것을 BERT[3]로 인코딩한 것을 video feature로 사용하였습니다.&lt;/li&gt;
      &lt;li&gt;이러한 형태의 Feature는 salient한 object와 action을 단어의 형태로 explicit하게 제시해 줄 수 있어 자연어 쿼리와 쉽게 연관지을 수 있습니다.&lt;/li&gt;
      &lt;li&gt;크기: L*d&lt;sub&gt;BERT&lt;/sub&gt;, d&lt;sub&gt;BERT&lt;/sub&gt;는 BERT embedding의 차원&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Object Detection Feature
    &lt;ul&gt;
      &lt;li&gt;프레임마다 top-k detection의 RoI Feature를 video feature로 사용하였습니다.&lt;/li&gt;
      &lt;li&gt;Image Captioning Feature는 salient object만을 잡아서 제시하는 반면, 이 Feature는 salient하지 않은 object도 제시해 줄 수 있습니다.&lt;/li&gt;
      &lt;li&gt;크기: L*k*d&lt;sub&gt;obj&lt;/sub&gt;, k는 샘플링 된 오브젝트의 수, d&lt;sub&gt;obj&lt;/sub&gt;는 object feature의 차원&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;feature-wise-ensemble&quot;&gt;Feature-Wise Ensemble&lt;/h2&gt;

&lt;p&gt;현재까지의 NLVL 모델은 여러 종류의 Video Feature를 이용할 때 단순히 Feature들을 Concat하였습니다. 하지만 이러한 방식은 각 Feature별 특징을 고려하지 않고 model optimization을 하기 때문에, 각 Feature를 제대로 이용한다고 보기 어렵습니다.&lt;/p&gt;

&lt;p&gt;따라서 개선된 모델에서는 각각의 video feature마다 작은 모델을 학습하고 이를 ensemble하는 방법을 사용하였습니다.&lt;/p&gt;

&lt;h1 id=&quot;결과&quot;&gt;결과&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;프로젝트 규정상 자세한 내용을 공개할 수 없는 점 양해 부탁드립니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;가장 중요하고 널리 사용되는 metric인 R@1(Top-1 Accuracy)에서 37.8으로 ASST[2]의 32.4보다 훨씬 높은 성능을 얻을 수 있었습니다.&lt;/p&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;기계학습에서 유명한 격언으로 “악마는 디테일에 있다”라는 말이 있습니다. 이 말대로라면 비디오와 자연어의 조합은 분명 악마 중에서도 가장 사악한 종류일 것입니다.&lt;/li&gt;
  &lt;li&gt;데이터를 처리하기 위해 알아야 할 디테일(노하우)은 많았지만 관련된 정보를 얻을 방법은 극히 제한적이었습니다. 이 때 &lt;em&gt;타 연구자를 만나고 그들에게서 관련 노하우를 얻은 것&lt;/em&gt;이 도움이 많이 되었습니다.
    &lt;ul&gt;
      &lt;li&gt;프로젝트를 시작할 당시 연구실 내에 자연어나 비디오를 처리해 본 사람이 없었기 때문에 모든 것을 제가 직접 부딛혀 보고 알아내야 할 처지였습니다.&lt;/li&gt;
      &lt;li&gt;그러나, 혼자 모든 것을 시도해 보는 것은 현실적으로 어려웠기 때문에 &lt;em&gt;타 연구자를 만나고 그들에게서 관련 노하우를 얻어보려는&lt;/em&gt;노력을 많이 했습니다. 몇몇 유명 학회(ICCV,KCCV)에 직접 참여하여 국내 유수 연구진들을 만나 비디오 처리에 관한 조언을 들었고, 우연한 기회로 버클리에서 근무하시는 한국인 연구자 분을 만나 자연어 처리에 관한 노하우를 얻었습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;[1] Hendricks et al. “Localizing Moments in Video with Temporal Language”, ICCV, 2017&lt;/p&gt;

&lt;p&gt;[2] Ning et al. “An Attentive Sequence to Sequence Translator for Localizing Video Clips by Natural Language”, In IEEE Transactions on Multimedia, 2020&lt;/p&gt;

&lt;p&gt;[3] Devlin et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”, Arxiv preprint, 2018&lt;/p&gt;
</description>
        <pubDate>Wed, 09 Sep 2020 22:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2020/09/09/NLVL/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2020/09/09/NLVL/</guid>
        
        <category>Vision and Language</category>
        
        
      </item>
    
      <item>
        <title>Large Image Obfuscation</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;현재 실제 한 기업의 서비스와 큰 관련이 있습니다. 많은 디테일이 생략되었습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;이 포스트를 읽기 전에, &lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;를 먼저 읽고 와 주세요.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;obfuscation-for-large-image&quot;&gt;Obfuscation for Large Image&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;에서, 우리는 성공적으로 이미지를 비식별화 하여 &lt;em&gt;이미지 활용성&lt;/em&gt; 과 &lt;em&gt;익명성&lt;/em&gt; 의 두 가지의 목표를 모두 달성하는 것을 보았습니다.&lt;/p&gt;

&lt;p&gt;그러나, &lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;의 Obfuscator는 실제로 현장에서 사용하기엔 많은 무리가 있습니다. 단순히 개념 실증을 위해 만든 모델이어서, Obfuscator가 크기 128*128 이상의 이미지에서는 잘 작동하지 않기 때문입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/large_obfus/large_fail.jpg&quot; alt=&quot;Obfuscation for big image fails&quot; /&gt;&lt;/p&gt;

&lt;p&gt;일반적으로, &lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;의 모델을 128*128 이상의 이미지에 적용하면 위의 그림과 같은 결과가 나옵니다: Obfuscator에 Modal Collapse가 일어나 같은 이미지만 만들거나, 학습이 Task loss에 Dominate되어 원본과 똑같은 이미지를 만들거나.&lt;/p&gt;

&lt;p&gt;저는 이전의 Obfuscator를 개량하여, 실 사용이 가능한 수준의 모델을 만들기 위한 선행연구를 진행하였습니다.&lt;/p&gt;

&lt;h1 id=&quot;idea&quot;&gt;Idea&lt;/h1&gt;

&lt;p&gt;커다란 이미지에서 이전의 Obfuscator가 잘 작동하지 못하는 이유는 두 가지입니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;GAN 구조의 문제
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;의 Obfuscator는 DCGAN[1]의 파생으로, 학습이 불안정하고 큰 이미지는 다루지 못하는 문제가 있습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Generation 자체의 어려움
    &lt;ul&gt;
      &lt;li&gt;이미지가 커지면, 가능한 이미지의 경우의 수가 기하급수적으로 늘어나 Generator 학습에 문제가 되는 것으로 알려져 있습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;소개한 두 가지의 문제를 해결하기 위해, 아래와 같은 해결법을 제시하였습니다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Obfuscator를 비교적 큰 이미지에서도 잘 동작하는 구조로 바꾸었습니다.
    &lt;ul&gt;
      &lt;li&gt;최근의 연구 결과에 따르면, Energy-Based GAN의 파생형[2][3]이 커다란 이미지에서도 어느 정도 작동한다고 알려져 있습니다.&lt;/li&gt;
      &lt;li&gt;BEGAN[3]을 직접 구현하여 Obfuscator에 적용하였습니다
        &lt;ul&gt;
          &lt;li&gt;제대로 된 BEGAN 구현체가 없어 직접 구현하여 사용하였습니다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Obfuscator가 Original Image가 아닌 Pre-Trained Target Task Netowrk의 Featuremap으로부터 Obfuscated Image를 생성하게 바꾸었습니다.
    &lt;ul&gt;
      &lt;li&gt;이미지 크기를 N*N, Featuremap 크기를 m*m이라고 했을 때, 기존의 Obfuscator는 N*N -&amp;gt; N*N의 매핑을 학습해야 했지만, 이제는 m*m -&amp;gt; N*N의 비교적 작은 매핑을 학습하게 됩니다.&lt;/li&gt;
      &lt;li&gt;Target Task의 Featuremap은 Target Task와 관련된 정보는 가지고 있고, Target Task와 관련 없는 정보는 가지고 있지 않습니다.
        &lt;ul&gt;
          &lt;li&gt;따라서, Featuremap으로부터 Obfuscated Image를 생성하면 Obfuscator는 더 이상 이미지의 어떤 부분이 Task와 관련 있고 어떤 부분이 관련 없는지 학습하지 않아도 됩니다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Neural Network Visualization분야의 연구 결과에 따르면, Target Task Featuremap은 이미지에서 의미를 가지는 기본 단위 (특징적인 점, 곡선 등)에 대한 정보를 많이 담고 있습니다
        &lt;ul&gt;
          &lt;li&gt;즉, Obfuscator는 더 이상 이미지에서 이러한 기본 단위를 찾을 필요가 없게 됩니다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;approach&quot;&gt;Approach&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;구체적인 방법은 공개할 수 없습니다. 양해 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;qualitative-results&quot;&gt;Qualitative Results&lt;/h1&gt;

&lt;h2 id=&quot;anonymity&quot;&gt;Anonymity&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/large_obfus/celeba-results.jpg&quot; alt=&quot;Obfuscation Results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림은 원본 이미지와 제안된 방법으로 생성된 Obfuscated Image를 비교하고 있습니다. 왼쪽의 두 예시는 Multi-Attribute Classification에 학습된 이미지이고, 오른쪽 두 예시는 Facial Landmark Detection에 학습된 이미지입니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;두 경우 모두, 원본을 알아보기 없을 만큼 Obfuscation이 잘 된 것을 볼 수 있습니다.&lt;/li&gt;
  &lt;li&gt;Multi-Attribute Classification에 학습된 obfuscation은 얼굴 형체를 뭉개는 반면, Facial Landmark Detection에 학습된 것은 얼굴 윤곽선을 어느 정도 보존하고 있습니다.
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;에서 설명한 것처럼, Obfuscator 이미지 매핑은 Target task에 필요 없는 정보를 지우기 때문입니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;difficulty-of-de-obfuscation&quot;&gt;Difficulty of De-obfuscation&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/large_obfus/celeba-reverse.jpg&quot; alt=&quot;Obfuscation Results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;에서 설명한 것처럼, 몇 장의 이미지를 제외한 대부분의 원본 이미지가 유출된 상황을 가정하고, Obfuscated image -&amp;gt; Original image매핑을 학습하여 보았습니다. 결과는 위의 그림과 같습니다.&lt;/p&gt;

&lt;p&gt;그림은 CelebA Dataset의 Facial Landmark Detection Task에 학습된 Obfuscator 모델을 보여줍니다. 위에서부터 차례대로 원본 이미지, Obfuscated Image, 그리고 복원된 이미지입니다.&lt;/p&gt;

&lt;p&gt;설령 원본 트레이닝 데이터가 유출되었다 하더라도, Obfuscator의 역방향 매핑을 학습한 모델은 Obfuscated Image를 잘 복원하지 못하는 모습을 볼 수 있습니다. &lt;a href=&quot;https://skaws2003.github.io/2019/05/15/obfuscation/&quot;&gt;이전 포스트&lt;/a&gt;에서 설명했던 것처럼, Obfuscation 과정에서 Task와 관련 없는 정보가 지워졌기 때문입니다.&lt;/p&gt;

&lt;h1 id=&quot;quantitative-results&quot;&gt;Quantitative Results&lt;/h1&gt;

&lt;h2 id=&quot;target-task-performance--privacy-protection&quot;&gt;Target Task Performance &amp;amp; Privacy Protection&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/large_obfus/taskperf.jpg&quot; alt=&quot;Target task performance&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 표는 Multi-Attribute Classification과 Facial Landmark Detection 두 가지 Task에 대한 성능입니다. 표에서, Unit 옆의 화살표는 수치가 높을 수록 좋은지, 낮을 수록 좋은지 보여줍니다. 예를 들어, AUC↑는 값이 높을 수록 성능이 뛰어나단 뜻입니다.&lt;/p&gt;

&lt;p&gt;먼저, 제안된 모델의 Target Task performance는 Multi-Attribute Classification에서는 원본과 거의 비슷한 성능을 보였고, Facial Landmark Detection에서는 원본보다는 못하지만 다른 obfuscation(Noise)보다는 훨씬 나은 수치를 보였습니다.&lt;/p&gt;

&lt;p&gt;한편 Face Varification Accuracy에서는 제안된 모델이 50%에 가까운 성능을 보여 Face varification모델을 성공적으로 속였음을 볼 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;참고: 
Face varification accuracy(FV. Acc.)는 같은 사람을 찍은 두 개의 사진이 있을 때 Face varification 모델이 두 사진이 같은 사람을 찍을 것인지 알아맞출 확률입니다. 
Obfuscation이 잘 되었을 경우, Face varification 모델은 랜덤한 값을 내게 되어 Fv. Acc. = 50%에 가까워지게 됩니다. 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;비록 선행연구이기는 했지만, 논문 연구에서 출발해 실제로 산업에서 쓰일 만한 모델을 만드는 경험을 했다.
    &lt;ul&gt;
      &lt;li&gt;논문을 쓰는 연구와 산업에 쓰이는 연구는 다르다. 이러한 점을 많이 체감했다.&lt;/li&gt;
      &lt;li&gt;많은 오픈소스를 빠르게 적용하고 성능을 시험하는 능력이 많이 늘었다.
        &lt;ul&gt;
          &lt;li&gt;특히 모델에 사용할 GAN 아키텍쳐를 정하는 과정에서 많은 오픈소스를 검토했다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;실제로 쓰일 모델은 연산 자원이나 메모리 자원도 충분히 고려해서 만들어야 한다. 이러한 부분을 신경쓰며 연구하는 경험을 했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;p&gt;[1] “Unsupervised Representation Learning With Deep Convolutional Generative Adversarial Networks”, In ICLR, 2016&lt;/p&gt;

&lt;p&gt;[2] “Energy-based Generative Adversarial Network”, In ICLR, 2017&lt;/p&gt;

&lt;p&gt;[3] “BEGAN: Boundary Equilibrium Generative Adversarial Networks”, 2017&lt;/p&gt;
</description>
        <pubDate>Tue, 01 Oct 2019 22:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2019/10/01/large-obfuscation/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2019/10/01/large-obfuscation/</guid>
        
        <category>Image Security</category>
        
        
      </item>
    
      <item>
        <title>PyTorch-MFCC</title>
        <description>&lt;h1 id=&quot;project-description-mfcc-for-pytorch&quot;&gt;Project Description: MFCC for PyTorch&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;#후기&quot;&gt;디테일한 내용을 생략하고 후기로 넘어가려면 여기를 클릭&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MFCC는 현재 가장 인기 있는 오디오 특징값 추출 알고리즘입니다 (알고리즘에 대한 자세한 설명은 &lt;a href=&quot;https://brightwon.tistory.com/11&quot;&gt;여기&lt;/a&gt;를 참조).
특히 이 알고리즘은 최근 음성인식/장르인식 등을 위한 기계학습 모델에서 오디오 데이터의 전처리 기법으로 널리 사용되고 있습니다.
그러나 2019년 6월 현재 PyTorch에서는 이 알고리즘을 지원하지 않고 있습니다.
현재 MFCC는 &lt;a href=&quot;https://github.com/jameslyons/python_speech_features&quot;&gt;python_speech_features&lt;/a&gt;와 같은 라이브러리를 통해 추출되고 있으나, 이들은 PyTorch와의 호환성이 없어 PyTorch의 강력한 Autograd를 사용할 수 없다는 치명적인 약점이 있습니다. 
이 때문에 PyTorch에서 MFCC를 사용할 때는 Data Augmentation과 같이 인풋 데이터가 수시로 바뀌는 알고리즘은 사용하기가 매우 까다로웠습니다.&lt;/p&gt;

&lt;p&gt;위와 같은 이유로 이 프로젝트에서는 PyTorch Autograd와 잘 연계되는 MFCC 추출 라이브러리를 작성하는 것을 목표로 하였습니다. 이를 위해, 여기서는 MFCC 추출 과정을 처음부터 끝까지 직접 PyTorch로 구현하였습니다.&lt;/p&gt;

&lt;h1 id=&quot;결과&quot;&gt;결과&lt;/h1&gt;
&lt;h2 id=&quot;achievements&quot;&gt;Achievements&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;기존 라이브러리인 &lt;a href=&quot;https://github.com/jameslyons/python_speech_features&quot;&gt;python_speech_features&lt;/a&gt;와 1e-5 미만의 작은 값 차이만을 보임&lt;/li&gt;
  &lt;li&gt;Fully Differentiable with PyTorch!&lt;/li&gt;
  &lt;li&gt;2021년 2분기 기준 Github Star 26개를 가지고 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;drawbacks&quot;&gt;Drawbacks&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;2020년 연말 이후로 &lt;a href=&quot;https://pytorch.org/audio/stable/index.html&quot;&gt;TorchAudio&lt;/a&gt;에서 공식 지원하는 기능임. 따라서 현재는 archive 상태&lt;/li&gt;
  &lt;li&gt;Numerically unstable할 가능성이 있음
    &lt;ul&gt;
      &lt;li&gt;Issue로 지적된 부분으로, 중간의 logarithm 부분에 epsilon을 더하지 않은 것이 unstablity를 유발할 가능성이 있음&lt;/li&gt;
      &lt;li&gt;MFCC를 수식 그대로 구현하였기 때문에 생긴 문제로 보임&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;짧기는 하지만 많은 사람에게 공개될 코드이기 때문에 코멘팅에 대해 많은 고민을 했다. PyTorch 및 다른 유명한 라이브러리 다수에서 어떤 식으로 코멘팅을 하는 지, 어떤 식으로 문서화에 대비하는지를 배우는 데 시간을 많이 사용해야 했다.&lt;/li&gt;
  &lt;li&gt;돌이켜 보자면, 이 프로젝트에서 코멘팅에 대해 많은 고민을 한 덕분에 이후 코딩 협업에서 큰 문제가 없었던 것 같다.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 17 Aug 2019 22:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2019/08/17/pytorch-mfcc/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2019/08/17/pytorch-mfcc/</guid>
        
        <category>Audio Processing</category>
        
        
      </item>
    
      <item>
        <title>Image Obfuscation</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;현재 실제로 기업에서 사용 중인 프로젝트입니다. 많은 디테일이 생략되었습니다&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;image-obfuscation&quot;&gt;Image Obfuscation&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://www.deepingsource.io/privacy-protection?lang=ko&quot;&gt;Image Obfuscation에 대한 내용은  Deeping Source Inc.의 공식 문서를 참조&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;objective&quot;&gt;Objective&lt;/h2&gt;

&lt;p&gt;Image obfuscation은 이미지 데이터셋을 처리하여 이미지가 다음의 두 가지 성질을 만족하도록 하는 것입니다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;익명성: 이미지 내부의 개인정보(얼굴 등)은 사람이 알아볼 수 없는 형태로 가공되어야 하며, 제 3자가 원본을 복원할 수도 없어야 합니다.&lt;/li&gt;
  &lt;li&gt;데이터 활용도: 어떤 특정 Task에 대하여 (e.g. Facial landmark detection, gaze estimation), 익명화된 이미지로 해당 task를 다루는 기계학습 모델을 학습시키더라도 원본 이미지로 학습한 것과 비슷한 성능을 내어야 합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;previous-works&quot;&gt;Previous Works&lt;/h2&gt;

&lt;p&gt;기존의 Image obfuscation 방식에는 다음과 같은 것들이 있습니다:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;프라이버시와 관련된 부분 (예, 얼굴, 주소)을 찾아낸 뒤 해당 부분을 지우거나[1] GAN을 활용하여 변조하는 방식[2]
    &lt;ul&gt;
      &lt;li&gt;프라이버시를 탐지하는 모델을 학습하기 위해 많은 데이터를 필요로 합니다&lt;/li&gt;
      &lt;li&gt;프라이버시와 관련된 부분을 제대로 탐지하지 못할 위험이 있습니다. (익명성 보장의 문제)&lt;/li&gt;
      &lt;li&gt;지우거나 변조된 부분에 관한 Task는 학습할 수 없습니다. 예를 들어, 얼굴을 지울 경우 Facial Landmark detection은 학습하지 못합니다. (데이터 활용성의 문제)&lt;/li&gt;
      &lt;li&gt;이미지로 어떤 Task를 학습하더라도 좋은 결과를 기대할 수 없습니다 (데이터 활용성의 문제)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;아예 이미지를 초저해상도로 만든 뒤 초저해상도에서도 작동하는 모델을 학습하는 방식[3]
    &lt;ul&gt;
      &lt;li&gt;초저해상도 이미지를 사용하므로 학습된 모델의 성능을 기대할 수 없습니다 (데이터 활용성의 문제)&lt;/li&gt;
      &lt;li&gt;데이터 활용성을 위해 해상도를 높이면 익명화가 제대로 되지 않을 수 있습니다 (익명성 보장의 문제)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위에서 설명한 것처럼, 기존의 방법은 이미지의 활용도를 떨어뜨릴 뿐더러, 개인정보 탐지 과정에서 개인정보를 놓칠 경우 익명성이 보장되지 않을 수도 있다는 치명적인 문제가 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;approach&quot;&gt;Approach&lt;/h1&gt;

&lt;h2 id=&quot;idea&quot;&gt;Idea&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;GAN기반의 Generative model을 사용하여 obfuscated image를 생성
    &lt;ul&gt;
      &lt;li&gt;이미지 전체를 익명화할 수 있으므로 익명성이 제대로 보장된다&lt;/li&gt;
      &lt;li&gt;이미지 전체를 익명화하면서도 데이터 활용성을 보장하려면, Image generation과정에 직접 supervision을 줄 수 있는 GAN이 적절하다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Target Task에 대한 데이터 활용성을 보장하기 위해 Original Image에 Pre-train된 target task network를 사용
    &lt;ul&gt;
      &lt;li&gt;Pre-trained target task network로부터의 피드백을 통해 이미지에서 task와 관련된 부분은 남기고 task와 관련 없는 부분은 지워질 수 있도록 한다.&lt;/li&gt;
      &lt;li&gt;위와 같은 방식으로, Obfuscator는 Target task performance를 보존하면서도 익명화는 제대로 하는 Image mapping function을 학습하게 된다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;overall-usage-scenario&quot;&gt;Overall Usage Scenario&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/scenario.jpg&quot; alt=&quot;Usage Scenario&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림은 우리 Image Obfuscation이 어떤 방식으로 이용될 수 있는 지 보여줍니다.&lt;/p&gt;

&lt;p&gt;Image obfuscation에 관련된 사람은 프라이버시 걱정 없이 이미지를 배포하려는 사람(&lt;em&gt;이미지 배포자&lt;/em&gt;), 배포된 이미지로 모델을 학습하려는 사람(&lt;em&gt;이미지 사용자&lt;/em&gt;)의 두 가지 분류로 나눌 수 있습니다.&lt;/p&gt;

&lt;p&gt;위의 그림에서, 이미지 배포자는 아래와 같은 일을 합니다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Obfuscator를 통해 이미지를 비식별화&lt;/li&gt;
  &lt;li&gt;비식별화된 이미지를 배포&lt;/li&gt;
  &lt;li&gt;Obfuscator에 Distillation된 모델(Distillated Obfuscator)을 배포&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이미지를 이용하려는 이미지 사용자는, 배포된 자료를 가지고 다음과 같은 일을 합니다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;비식별화된 이미지를 사용해 Target Task 모델을 학습&lt;/li&gt;
  &lt;li&gt;학습된 모델을 이용해 Inference할 때는, Distillated Obfuscator를 이용해 인풋 이미지를 Obfuscated Image와 비슷하게 만들어서 Inference 수행&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;obfuscator-학습&quot;&gt;Obfuscator 학습&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/training.jpg&quot; alt=&quot;Obfuscation Training Procedure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obfuscator 모델(&lt;strong&gt;O&lt;/strong&gt;)을 학습하기 위해 Adversarial Training 및 Multi-task learning기법을 사용하였습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;먼저 이미지를 익명화하기 위해 Reference Obfuscation(Noise, Jittering 등의 합성)된 이미지를 만들고, 이것을 Generation Target으로 하여 obfuscated image를만드는 Adversarial Training을 합니다.
    &lt;ul&gt;
      &lt;li&gt;이 과정에서 Obfuscator(&lt;strong&gt;O&lt;/strong&gt;)는 주어진 이미지로부터 reference obfuscation과 최대한 비슷하게 생긴 이미지를 만드는 방법을 학습하게 됩니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;위에서 나오는 Obfuscated Image(Generator output)를 Pre-train된 Target task network(&lt;strong&gt;F&lt;/strong&gt;)에 input으로 넣어 prediction이 제대로 되는지 확인합니다.
    &lt;ul&gt;
      &lt;li&gt;이 과정에서 Obfuscator(&lt;strong&gt;O&lt;/strong&gt;)는 인풋 이미지에서 Target Task에 필요한 정보는 남기고 필요없는 정보는 지워서 이미지를 사람이 인식하지 못하는 형태로 바꾸는 법을 학습합니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;obfuscated-image-이용&quot;&gt;Obfuscated Image 이용&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/inference.jpg&quot; alt=&quot;Usage&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obfuscated Image를 배포할 때, 사용자에는 다음의 두 가지 자료가 주어집니다:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Obfuscated Image
    &lt;ul&gt;
      &lt;li&gt;원본 이미지는 주어지지 않습니다&lt;/li&gt;
      &lt;li&gt;비식별화된 이미지만이 주어지므로 프라이버시를 효과적으로 보호할 수 있습니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Diltillated Obfuscator
    &lt;ul&gt;
      &lt;li&gt;학습된 Task model로 Inference할 때 필요합니다&lt;/li&gt;
      &lt;li&gt;Obfuscator의 Inverse mapping을 학습하는 것을 막기 위해 원본 Obfuscator는 주어지지 않습니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 두 자료를 가지고, 사용자는 다음과 같이 Obfuscated Image를 이용할 수 있습니다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;비식별화된 이미지를 사용해 Target Task 모델을 학습&lt;/li&gt;
  &lt;li&gt;학습된 모델을 이용해 Inference할 때는, Distillated Obfuscator를 이용해 인풋 이미지를 Obfuscated Image와 비슷하게 만들어서 Inference 수행
    &lt;ul&gt;
      &lt;li&gt;사용자가 학습된 모델을 배포하고 싶다면, 단순히 Diltillated Obfuscator와 학습된 Target Task Model을 이어붙여 배포하면 됩니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;how-it-works&quot;&gt;How it Works?&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/scheme.jpg&quot; alt=&quot;Obfuscation Mapping&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 그림은 Obfuscator 모델이 어떻게 동작하는 지 설명하는 그림입니다. 그림에서 &lt;strong&gt;O&lt;/strong&gt; 는 Obfuscator 매핑, F는 원본 이미지에 학습된 Target Task 모델의 Decision Boundary, F0는 Obfuscated Image에 학습된 Target Task 모델의 Decision Boundary입니다.&lt;/p&gt;

&lt;p&gt;그림에서 Obfuscator(&lt;strong&gt;O&lt;/strong&gt;)는 회색 영역의 원본 이미지를 노란색 영역으로 매핑하는 역할을 합니다. 그런데 이 Obfuscator는 Target Task의 Decision Boundary를 최대한 유지하도록 학습되었기 때문에 이미지의 형태는 다르게 하면서도(&lt;strong&gt;O&lt;/strong&gt; 매핑) 원본 이미지에 대한 Target Task 모델의 Decision Boundary는 비슷하게 (회색 영역에서 F와 F0 비교) 유지할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;qualitative-results&quot;&gt;Qualitative Results&lt;/h1&gt;

&lt;p&gt;아래는 다양한 Task에 대한 Obfuscation 결과입니다. 총 3가지 Task (Multi-Attribute Classification, Facial Landmark Detection, Gaze Estimation)에 대해 실험했습니다.&lt;/p&gt;

&lt;h2 id=&quot;multi-attribute-classification&quot;&gt;Multi-Attribute Classification&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/mulatt_results.jpg&quot; alt=&quot;Multi-Attribute Classification Results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obfuscated Image에서,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;아래의 둘과 다르게 &lt;strong&gt;색에 관한 정보가 어느 정도 남아있습니다&lt;/strong&gt;.
    &lt;ul&gt;
      &lt;li&gt;Multi-Attribute Classification이 &lt;em&gt;“금발”, “흑인”, “립스틱”&lt;/em&gt; 등 색에 관한 질문을 하기 때문입니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;아래의 둘과 달리, &lt;strong&gt;머리카락이 잘 보입니다&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Multi-Attribute Classification이 &lt;em&gt;“긴 머리”, “대머리”, “곱슬머리”&lt;/em&gt; 등의 질문을 하기 때문입니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;facial-landmark-detection&quot;&gt;Facial Landmark Detection&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/landmark_results.jpg&quot; alt=&quot;Facial Landmark Detection Results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obfuscated Image에서,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;원본 이미지의 대부분이 노이즈로 대체되었으며, 얼굴의 윤곽만을 간신히 알아볼 수 있습니다.
    &lt;ul&gt;
      &lt;li&gt;Facial Landmark Detection에는 얼굴의 특징점 몇 가지를 찾이 위한 정보를 빼면 아무것도 필요하지 않기 때문입니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;gaze-estimation&quot;&gt;Gaze Estimation&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/gaze_results.jpg&quot; alt=&quot;Gaze Estimation Results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obfuscated Image에서,&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;얼굴 하관이 지워져 있습니다
    &lt;ul&gt;
      &lt;li&gt;눈 쪽은 잘 보이지만, 입과 그 아랫쪽은 잘 보이지 않습니다&lt;/li&gt;
      &lt;li&gt;얼굴 하관은 시선의 위치와 큰 관련이 없기 때문입니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;해석&quot;&gt;해석&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Obfuscated Image는 원본 이미지와 크게 다릅니다
    &lt;ul&gt;
      &lt;li&gt;프라이버시를 효과적으로 보호할 수 있습니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Target Task의 특성에 따라 Obfuscation이 달라지는 것을 볼 수 있습니다
    &lt;ul&gt;
      &lt;li&gt;이를 볼 때, 우리의 Obfuscator는 실제로 Target Task에 필요한 정보는 남기고 다른 정보는 지우는 식으로 동작함을 알 수 있습니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;difficulty-of-de-obfuscation&quot;&gt;Difficulty of De-obfuscation&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/inverse.jpg&quot; alt=&quot;inverting obfuscation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;어떤 악의적인 사용자는 Obfuscated Image를 다시 원본으로 복원하려 시도할 수도 있습니다. 우리 Obfuscation이 이러한 복원 시도에 얼마나 강한지 알아보기 위해, 다음과 같이 최악의 상황을 가정하였습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;악의적인 사용자가 약 20개의 이미지를 제외한 대부분의 Original Image를 가지고 있다&lt;/li&gt;
  &lt;li&gt;악의적인 사용자는 Obfuscated Image -&amp;gt; Original Image의 mapping을 학습하여 배포된 Obfuscated Image를 복원하려 시도한다&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 이미지는 이러한 상황에서 복원 시도가 어떻게 되었는지 보여줍니다. 악의적인 사용자가 대부분의 original image - obfuscated image의 쌍을 가지고 있더라도, 악의적인 사용자는 원본 이미지를 복원할 수 없습니다. 이는 아래의 두 가지 이유 때문입니다:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;사용자는 원본 Obfuscator가 아닌 Distilled Obfuscater만을 가지고 있기 때문에 원본 Obfuscator의 매핑을 학습할 수 없습니다&lt;/li&gt;
  &lt;li&gt;Obfuscator가 Target Task와 관련없는 정보를 지웠기 때문에 원본 이미지를 재건하는 데 필요한 정보가 부족합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;quantitative-results&quot;&gt;Quantitative Results&lt;/h1&gt;

&lt;h2 id=&quot;target-task-performance&quot;&gt;Target Task Performance&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/task_performance.jpg&quot; alt=&quot;Target Task Performance&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 표는 여러 종류의 Obfuscated Image로 학습했을 때의 Target task performance를 보여줍니다. 표에서, Unit 옆의 화살표는 수치가 높을 수록 좋은지, 낮을 수록 좋은지 보여줍니다. 예를 들어, AUC↑는 값이 높을 수록 성능이 뛰어나단 뜻입니다.&lt;/p&gt;

&lt;p&gt;모든 Task와 모든 Dataset에서, 우리 Obfuscator는 Baseline obfuscation(Blur, Noise 등)에 비해 크게 높은 성능을 보였습니다. 또한, Origianl Image로 학습한 모델과도 크게 차이 없는 성능을 보였습니다.&lt;/p&gt;

&lt;p&gt;이로 미루어 볼 때, 우리 모델은 이미지의 활용성을 제대로 보존하고 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;privacy-protection&quot;&gt;Privacy Protection&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/obfus/fvacc.jpg&quot; alt=&quot;Face Varification Acc.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 표는 여러 종류의 Obfuscated Image에 Face varification을 수행하였을 때의 결과입니다.&lt;/p&gt;

&lt;p&gt;Metric 인 Face varification accuracy(FV. Acc.)는 같은 사람을 찍은 두 개의 사진이 있을 때 Face varification 모델이 두 사진이 같은 사람을 찍을 것인지 알아맞출 확률입니다. Obfuscation이 잘 되었을 경우, Face varification 모델은 랜덤한 값을 내게 되어 Fv. Acc. = 50%에 가까워지게 됩니다.&lt;/p&gt;

&lt;p&gt;모든 경우에서, 우리 Obfuscator는 Face varification 모델을 완전히 속여 50%에 극도로 가까운 FV. Acc.를 내게 만들었습니다.&lt;/p&gt;

&lt;p&gt;위의 결과로 볼 때, 우리 모델은 프라이버시를 제대로 지킬 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;프로젝트가 한창 진행되던 중간에 끼어들어 배울 것이 많았다.
    &lt;ul&gt;
      &lt;li&gt;처음 팀에 들어왔을 때, 일단 관련 분야의 중요한 논문들을 추천해 달라고 부탁했다. 그것들을 공부해 배경 지식을 쌓았다&lt;/li&gt;
      &lt;li&gt;이미 짜여져 있는 코드를 이해하기 위해 디버거를 활용하여 코드가 돌아가는 과정을 쭉 훓어보았다.
        &lt;ul&gt;
          &lt;li&gt;훑어보는 과정에서, 특히 프로젝트 코드의 디자인 패턴을 이해하고 이를 체득하려 노력했다.&lt;/li&gt;
          &lt;li&gt;이 과정 덕분에 이후 실제 코딩을 할 때 큰 마찰이 없었다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;모르는 것이 있을 때마다 머뭇거리지 않고 적극적으로 질문했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;다른 사람과 제대로 된 협업을 하는 것은 이 프로젝트가 처음이었다. 이 때문에 업무상의 커뮤니케이션에서 많은 것을 배웠다.
    &lt;ul&gt;
      &lt;li&gt;특히, 커뮤니케이션에서 가장 중요하지만 쉽게 있는 것들에 대해 많이 신경쓰게 되었다.&lt;/li&gt;
      &lt;li&gt;말로 하는 커뮤니케이션에는 항상 misunderstanding의 위험이 있다는 것을 체감했다.
        &lt;ul&gt;
          &lt;li&gt;새로운 개념을 설명하기 위해 기존에 없는 합성어를 만들어내지 않고 되도록 풀어서 설명하게 되었다&lt;/li&gt;
          &lt;li&gt;복잡한 개념을 설명할 때는 일단 그림부터 그리고 보게 되었다.&lt;/li&gt;
          &lt;li&gt;말로 무언가를 설명할 때는 항상 중간중간 이해도를 체크하게 되었다&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;주기적인 업데이트의 중요성을 많이 체감했다
        &lt;ul&gt;
          &lt;li&gt;연휴가 겹치고, 각자 맡은 일도 달라서 열흘 정도 서로 업데이트를 하지 않았던 적이 있다. 업데이트를 하지 않으니 이후 아이디어를 나누는 데 많은 어려움이 있었다.&lt;/li&gt;
          &lt;li&gt;이후로는 어떻게든 시간을 만들어서라도 1주일에 두 번 정도는 팀원과 업데이트를 하려고 노력하고 있다&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;p&gt;[1] “Face/off:  Preventing privacy leakage fromphotos in social networks”, In CCS, 2015&lt;/p&gt;

&lt;p&gt;[2] “DeepPrivacy: A Generative Adversarial Network for Face Anonymization”, In ISVC, 201919&lt;/p&gt;

&lt;p&gt;[3] “Privacy-Preserving Human Activity Recognition from Extreme Low Resolution”, In AAAI, 2017&lt;/p&gt;

</description>
        <pubDate>Wed, 15 May 2019 22:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2019/05/15/obfuscation/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2019/05/15/obfuscation/</guid>
        
        <category>Image Security</category>
        
        
      </item>
    
      <item>
        <title>Image-in-Image Steganography</title>
        <description>&lt;h1 id=&quot;image-in-image-steganography&quot;&gt;Image-in-Image Steganography&lt;/h1&gt;

&lt;p&gt;대학원에 입학하고 처음으로 수행한 온보딩 프로젝트입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/steganography/concept.jpg&quot; alt=&quot;Image Steganography&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림과 같이, 이미지 스테가노그래피는 이미지 속에 다른 정보 (텍스트, 이미지 등)를 숨기되 이미지 속에 정보가 숨어 있다는 사실을 다른 사람이 알지 못하게 하는 Task입니다.&lt;/p&gt;

&lt;p&gt;일반적인 암호화는 정보를 알아보지 못하게 하는 것을 목표으로 하나, 스테가노그래피는 정보가 숨겨져 있다는 사실 자체를 모르게 한다는 부분에서 암호화와 차이가 있습니다.&lt;/p&gt;

&lt;p&gt;현재 스테가노그래피 관련 연구는 이미지 안에 텍스트를 숨기는 기법에 집중되어 있습니다[1]. 이미지 안에 텍스트를 숨길 경우 픽셀당 숨겨지는 정보량(bpp, bits per pixel)은 0.1bit 내외인 반면, 이미지를 숨기면 bpp = 8bits * 3(RGB) = 24bits로 아주 어려운 문제가 되기 때문입니다.&lt;/p&gt;

&lt;p&gt;이러한 이유로, 최근 기계학습을 활용해 이미지 스테가노그래피를 하는 연구가 하나 등장했습니다[2]. 이 연구는 기본적인 LSB 인코딩 알고리즘보다는 보여주나, 여전히 (1)숨겨진 이미지가 쉽게 노출되고 (2) 이미지 변형에도 취약한[2] 문제를 가지고 있습니다.&lt;/p&gt;

&lt;p&gt;따라서, 이 프로젝트는 이전에 개발된 Image-in-Image Steganography 알고리즘[2]을 개량하여 다음의 두 가지 성질을 만족하게 하는 것을 목표로 하였습니다:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;숨겨진 이미지가 쉽게 보이지 않아야 한다
    &lt;ul&gt;
      &lt;li&gt;기존 알고리즘은 수치상(PSNR, SSIM등) 좋은 결과를 보여주었지만, 실제로는 숨긴 이미지가 생각보다 잘 보였습니다.&lt;/li&gt;
      &lt;li&gt;이미지의 경우, 대부분을 잘 숨기더라도 작은 edge 하나를 숨기지 못하면 금방 눈에 띄게 됩니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이미지가 어느 정도 변형되어도 안에 든 정보에는 문제가 없어야 한다
    &lt;ul&gt;
      &lt;li&gt;기존 알고리즘은 간단한 warping, jpeg compression등에도 안에 있는 정보가 쉽게 망가졌습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;previous-work-hiding-images-in-plain-sight&quot;&gt;Previous Work: Hiding Images in Plain Sight&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/steganography/prevwork.jpg&quot; alt=&quot;Previous work&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림에서, Cover Image는 겉으로 보이는 이미지, Secret Image는 숨겨질 이미지, Container Image는 Secret Image에 대한 정보를 가지고 있지만 겉보기에는 Cover 처럼 보이는 이미지, Recovered Image는 Container Image로부터 다시 끝&lt;/p&gt;

&lt;p&gt;모델은 Secret Image와 Cover Image로부터 Container Image를 만들어내는 Embedding network와 Container Image에서 Recovered Image를 생성하는 Recovering network로 나눠져 있습니다. 학습 시에는 이 둘이 같이 학습되며, 학습이 완료되면 메시지를 보내는 사람과 받는 사람이 각각 Embedding network와 Recovering network를 나눠 가집니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/steganography/prevresults.jpg&quot; alt=&quot;Previous results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 그림은 기존 알고리즘으로 Image-in-Image Steganography를 했을 때의 예시 두 가지입니다. 예시에서 Container Image를 자세히 보면, 위쪽 예시의 경우 하늘에서 사람의 윤곽이 보이고, 아래쪽 예시에서는 문고리 부분의 윤곽이 드러나는 것을 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;또, 그림에는 없지만, 만약 container Image를 약하게라도 변형할 경우, Recovered Image는 아무 의미 없는 Noise 형태로 변하게 됩니다.&lt;/p&gt;

&lt;h1 id=&quot;approach&quot;&gt;Approach&lt;/h1&gt;

&lt;h2 id=&quot;transformation-layer&quot;&gt;Transformation Layer&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/steganography/addtrans.jpg&quot; alt=&quot;Add Transform layer&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기존의 Taxt-in-Image 알고리즘[1]에서는, 뉴럴 네트워크 학습 과정에서 각종 이미지 변형(Warping, jpeg compression)을 시뮬레이션하는 Transofmration layer를 추가하는 방식으로 Container Image의 변형에 대응하였습니다.&lt;/p&gt;

&lt;p&gt;같은 방식으로, 저도 위의 그림과 같이 기존 모델에 Transformation layer를 추가하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;feature-encoding-secret-image&quot;&gt;Feature Encoding Secret Image&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/steganography/addcode.jpg&quot; alt=&quot;Encode input image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이전 기법[2]은 이미지의 대부분을 숨기더라도 일부의 edge를 놓쳐 결과적으로 숨겨진 이미지가 잘 보이는 문제가 있었습니다. 이러한 문제를 완화하기 위해, 저는 Embedding network와 Recovering network가 secret image 대신 Autoencoder로 인코딩된 secret image의 feature를 쓰도록 하였습니다.&lt;/p&gt;

&lt;p&gt;이렇게 하면, Edge에 관한 정보가 Container image에 explicit한 형태로 들어가지 않게 되어 Container image에서 Secret image의 edge가 보이는 현상을 완화할 수 있습니다.&lt;/p&gt;

&lt;h1 id=&quot;results&quot;&gt;Results&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/files/images/steganography/results.jpg&quot; alt=&quot;스테가노그래피 결과&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림은 프로젝트로 만들어진 모델의 결과물입니다. 위에서부터 차례대로 Cover Image(a), Secret Image(b), Container Image(c), Recovered Image(d)입니다.&lt;/p&gt;

&lt;p&gt;그림에서 보이다시피 Cover(a)에 Secret(b)를 숨겼음에도 둘을 합성한 Container Image(c)는 Cover(a)와 별다른 차이가 없는 것을 볼 수 있습니다. 마찬가지로 (c)에서 복원된 Recovered Image(d)는 원본 Secret Image(b)와 큰 차이 없는 것을 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;더하여, 모든 이미지는 합성된 이후에 각기 다른 수준의 변형을 거쳤으나(Rotation, jpeg compression 등), 결과물의 질은 변형의 강도와 크게 상관없이 좋습니다. 이것은 이전의 모델[2]에서는 불가능했던 것입니다.&lt;/p&gt;

&lt;h1 id=&quot;후기&quot;&gt;후기&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;연구실 온보딩을 겸해서 처음으로 해 본 연구 프로젝트였다
    &lt;ul&gt;
      &lt;li&gt;연구 프로젝트가 어떻게 진행되는 지 경험했다&lt;/li&gt;
      &lt;li&gt;실험 내역을 주기적으로 백업하는 습관을 들이는 계기가 되었다.
        &lt;ul&gt;
          &lt;li&gt;연구가 끝나고 6개월 쯤 지난 뒤에, 이 프로젝트 관련 내용이 필요해 찾으려고 보니 디스크가 망가져 실험 기록이 대부분 날아가 있는 것을 목격한 경험이 있다.&lt;/li&gt;
          &lt;li&gt;이 경험 이후로 실험을 하면 일단 구글 시트에 결과를 적어넣는 습관을 들였다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Steganography 관련 논문은 대부분 코드를 공개하지 않아 직접 Reproducing해야 했다
    &lt;ul&gt;
      &lt;li&gt;이 과정에서 논문을 보고 모델을 구현하는 경험을 많이 했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이미지 스테가노그래피를 해 보자는 생각은 순전히 나 혼자 떠올린 것이었다. 이 때문에 프로젝트를 시작하기에 앞서 많은 사람들에게 프로젝트를 PR해야 했다.
    &lt;ul&gt;
      &lt;li&gt;정기 랩 세미나 시간을 열심히 준비하여 기계학습 스테가노그래피 분야에 대한 소개와 내 아이디어에 대한 PR 시간으로 활용하였다. 열심히 준비한 만큼 좋은 반응을 얻어 프로젝트를 시작하는 데 많은 도움이 되었다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;[1] Jiren Zhu, Li Fei-Fei et al. “HiDDeN: Hiding Data with Deep Networks”, ECCV, 2018&lt;/p&gt;

&lt;p&gt;[2] Shumeet Baluja, “Hiding Images in Plain Sight: Deep Steganography”, NeurIPS, 2017&lt;/p&gt;
</description>
        <pubDate>Mon, 18 Feb 2019 22:00:00 +0900</pubDate>
        <link>https://skaws2003.github.io/2019/02/18/steganography/</link>
        <guid isPermaLink="true">https://skaws2003.github.io/2019/02/18/steganography/</guid>
        
        <category>Image Security</category>
        
        
      </item>
    
  </channel>
</rss>
