<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>오뚝이개발자</title>
    <link>https://otugi.tistory.com/</link>
    <description>넘어지면 다시 일어나는 &amp;quot;오뚝이개발자&amp;quot;의 블로그입니다.</description>
    <language>ko</language>
    <pubDate>Wed, 8 Jul 2026 21:59:50 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>땅어</managingEditor>
    <image>
      <title>오뚝이개발자</title>
      <url>https://tistory1.daumcdn.net/tistory/3729047/attach/eec6d7bbe2e347bebfbe862d1b564d09</url>
      <link>https://otugi.tistory.com</link>
    </image>
    <item>
      <title>오픽 잘 보는 법 (IH 등급 받는 방법, 오픽 벼락치기 꿀팁)</title>
      <link>https://otugi.tistory.com/396</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;최근 오픽 시험을 보았고 결과적으로 IH (Intermediate High) 등급을 받았다. 오픽은 토익 스피킹처럼 말하기 능력을 테스트하는 시험인데, 가상의 인터뷰어 Ava와 대화를 하게 된다. 나의 경우 오픽을 처음 보기도 했고, 괜히 두려운 마음에 IM (Intermediate Mid)을 받을 수 있는 난이도를 선택해서 시험을 보았다. 일반적으로 난이도 3, 4를 선택하면 IH를 받기 어렵다고 한다. 오픽의 경우 각 난이도마다 받을 수 있는 최고 등급이 어느 정도 정해져있는 편인데 IH, AL (Advanced Low)를 받기 위해선 일반적으로 난이도 5, 6을 선택해야 받을 수 있다고 한다. 아마 난이도 5, 6을 선택했다면 AL을 노려볼만 했을 수도 있을 것 같다. 현실적으로 난이도 3, 4를 선택해서 AL을 받는 것은 어렵기 때문이다. 일반적으로 이공계 기준 취업시 요구되는 스펙은 IL (Intermediate Low)이고, 문과 기준 IH 이상이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;총 공부기간은 약 1주일이었고, 여기서는 &lt;b&gt;내가 어떻게 1주만에 처음 응시하는 오픽에서 IH 등급을 받을 수 있었는지 그 방법에 대해 소개&lt;/b&gt;하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;137&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zUhPc/btsvdoxNroq/tKNKvq7UvFPoA3FjseHcyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zUhPc/btsvdoxNroq/tKNKvq7UvFPoA3FjseHcyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zUhPc/btsvdoxNroq/tKNKvq7UvFPoA3FjseHcyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzUhPc%2FbtsvdoxNroq%2FtKNKvq7UvFPoA3FjseHcyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;943&quot; height=&quot;137&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;137&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;들어가기게 앞서, 오픽이란 어떤 시험인가?&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;많은 사람들이 착각하는 부분이 오픽이란 시험이 영어 회화, 그러니까 자유 주제에 대한 프리 토킹을 얼마나 잘하는지를 평가하는 시험이라고 생각한다. 아주 틀린 말은 아니다. 하지만, 오픽은 단순히 프리 토킹을 측정하는 것이 아니라 &lt;b&gt;주어진 주제에 대해 얼마나 풍부하게 답변하는지를 측정&lt;/b&gt;하는 시험임을 인지해야 한다. 그러니까 질문을 상정하고 그에 대한 적절한 답변을 준비하는 것이 중요하다. 이렇게 범위를 설정하고 나면 막연하게 회화 능력을 올리도록 공부하는 것보다 훨씬 명확해진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;전략적인 Survey 선택 방법&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;오픽에는 survey를 선택하는 부분이 있다. 시험 시작 전 간단한 설문을 통해 응시자에게 물어볼 질문들을 선별하기 위함이다. 예컨대, 취미나 좋아하는 운동, 거주 환경, 직업 등을 물어본다. 중요한 점은 해당 survey를 기준으로 질문이 출제된다는 것이다. 그러니, 사실대로 답변하기 보다는 자신이 답변하기 편한 질문들이 출제되도록 전략적으로 선택하는 편이 좋다. 이게 매우 중요하다. &lt;b&gt;상대적으로 쉬운 질문들이 출제되는 설문은 분명 존재한다.&lt;/b&gt; 이에 대한 전략들은 인터넷에 많이 나와 있으니 찾아보면 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;내 기준 비추천하는 선택지는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;국내 여행, 해외 여행, 영화 감상, 공식적인 스포츠(야구, 농구, 축구, 골프 등)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 선택지들을 왜 비추천하는지 설명하겠다. 먼저 국내나 해외 여행의 경우 지형에 대해 물어보는 질문이 출제될 수 있다. 실제로 나의 경우 두 가지를 모두 선택했는데 &quot;국내나 해외 여행지에 방문했던 경험 중 인상 깊었던 경험과 해당 장소의 지형에 대해 설명하라&quot;는 질문이 나왔었다. 지형 같은 경우는 한국어로도 답변하기 어려운 문제다...그러니 여행 선택지는 되도록 피하기를 추천한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영화감상의 경우 &quot;좋아하는 영화는 무엇이고 해당 영화의 대략적인 줄거리는 어떻게 되는가?&quot;와 같은 문제가 출제될 수 있다. 영화 속에서 펼쳐지는 복잡한 사건들의 줄거리를 영어로 설명하기는 매우 어렵다. 또한 그러려면 각 배우들의 역할에 대해서도 설명을 해야하는데 이 또한 어려울 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;공식적인 스포츠들을 비추천하는 이유는 주로 규칙에 대한 질문이 나올 수 있기 때문이다. 야구나 축구와 같이 공식적인 rule이 정해져있고, 누군가와 함께 해야하는 스포츠의 경우 질문 유형이 굉장히 복잡해질 수 있다. 때문에 이 역시 피하기를 추천한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;오픽을 처음 접하는 사람들의 경우 자신이 선택한 설문 내용과 답변이 달라지면 감정이 될까봐 걱정하는 경우가 많다. 하지만, 실제로는 설문은 어디까지나 출제할 질문을 filtering 하기 위한 것이지 점수와 전혀 상관이 없다. 실제로 나의 경우도 취미나 여가로 여행을 선택했지만, 답변은 여행을 잘 하지 않는다고 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;전략적인 답변을 위한 가상의 페르소나 설정하기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;오픽과 비슷한 시험으로는 토익 스피킹이 있다. 나는 토익 스피킹도 이전에 응시해본 경험이 있다. 하지만 둘의 가장 큰 차이점은 &lt;b&gt;오픽의 경우 내가 문제를 이끌어갈 수 있다&lt;/b&gt;는 점이다! 토익 스피킹의 경우 사진 같은 자료를 주고 해당 상황을 묘사하는 자료에 기반한 문제들이 많이 출제된다. 따라서 어느 정도 정해진 답변을 해야하지만 오픽의 경우 내가 만들어 나아가기 나름이다. 그렇기 때문에 &lt;b&gt;답하기 편한 가상의 페르소나를 만들어두는 것이 좋다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;나의 경우 &lt;b&gt;&quot;일 경험이 없고, 학생이면서, 수업 등록 후 5년 이상이 지났고, 독신자로 개인 주택이나 아파트에 거주하며 집돌이에, 음악 감상을 좋아하고, 공원이나 해변 같은 곳에서 혼자 조용히 조깅하거나 집에서 요가하는 것을 좋아하고, 휴일엔 주로 혼자서 집에서 쉬면서 시간을 보내는&quot;&lt;/b&gt; 가상의 페르소나를 설정했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;되도록 혼자서 할 수 있는 활동들을 선택하는 편이 답하기에 유리하다. 가족이나 룸메와 살고있다거나, 타인과 함께 해야 하는 취미 활동들의 경우 &quot;다른 사람과의 트럽르 경험 그리고 이를 해결했던 방식&quot;에 대한 질문들이 출제될 수 있다. 하지만 혼자서 하는 활동들로 제한하면 타인과의 relationship에 대해 물어볼 수 없으니 질문들이 훨씬 간단하게 출제된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;바로바로 답할 수 있는 나만의 스토리 짜기!&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 이어지는 이야기인데, 각 &lt;b&gt;상황별로 스토리를 풍부하게 준비&lt;/b&gt;하기를 추천한다. 사실 우린 생각보다 많은 질문들에 한국어로도 답변을 못하는 경우들이 많다. 예컨대, 취미가 무엇인지, 최근 전자기기 관련 문제를 겪었던 경험과 이를 해결했던 방법, 여행을 가서 기억에 남았던 숙소 경험, 친구와의 약속을 취소하게 되었던 경험 등과 같이 말이다. 이들은 실제로 내가 받았던 질문들이다. 오픽은 토익 스피킹과 달라서, 오히려 발표에 가깝다고 생각하는 것이 좋다. 발표의 경우도 머릿 속에 어느 정도의 스토리나 대략적인 대본이 없으면 이야기할 때 헤메는 것과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;한국어로도 생각하지 못하는 답변을 영어로도 말하지 못한다.&lt;/b&gt; 그래서 다양한 상황들에 대해 내가 답변할 수 있는 가상의 스토리(진짜일 필요가 없다! 어차피 시험관들이 이야기한 내용의 진위여부를 판별할 것도 아니고!)들을 풍부하게 준비해두는 것이 좋다. 영어로 말하는 것은 그 다음 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;예시를 하나 들자면, 나의 경우 건강이라는 주제와 관련해 질문이 나올 것을 대비해 나만의 루틴에 대한 스토리를 다음과 같이 만들어 두었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I care about my health a lot. Maintaining health is one of the most important things in my life. I do regular exercise to stay healthy. I also try to eat healthy. I usually cook healthy meals at home to keep a balanced diet. I eat a lot of fruit and vegetables. In addition, I take health supplements like vitamin C and calcium&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 같이 대답할 수 있으려면, 평소에 내가 건강관리를 위해 하는 활동들을 열거식으로 말할 수 있어야 한다. 이 같은 스토리는 미리 준비해두지 않으면 시험장에서 바로바로 떠올리기가 쉽지 않다. 그러니 시험 전에 &quot;나는 건강을 위해서 좋은 음식을 먹으려 노력하고, 이를 위해 집에서 요리를 주로 해먹는 사람이다. 그리고 영양보조식품들도 섭취한다.&quot; 이렇게 가상의 나라는 인물에 대한 스토리르 만들어 두어야 한다. 시험장에서 영어로 말하기도 벅찬데 스토리까지 구상하려면 시간이 모자라다. 바로바로 답변이 나올 수 있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;첫 문제 자기소개 준비하기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이거에 대해서는 여러 의견이 있다. 자기소개는 공통문항이라 채점시 그다지 보지 않는다, 열심히 준비하지 않아도 된다는 사람들도 있는데, 나의 경우 그냥 이것도 열심히 준비하기를 추천한다. 첫 문항은 무조건 자기소개가 나온다. 그런데 첫 문항부터 말이 꼬이면 뒤에 문제들도 자신감이 하락해 제대로 답변하지 못한다. 채점 시 볼지 안볼지는 몰라도 잘 준비해서 답변하면 마이너스는 아닐 것이다. 나의 경우 아래와 같이 답변하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[소개] Hello, nice to meet you Ava! My name is ~, and I don't have an English name, so you can just call me ~. I'm 28 years old and I graduated from unviersity last year.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[전공] I majored in Computer Science and I'm looking for a job as a Machine Learning Engineer. I'm hopping to work at XX because it is the best company in the World.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[가족, 사는 곳] I live alone in a small studio apartment in Seoul and my parents live outside of Seoul with my sister. I visit them every month and we have dinner together.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[취미] My hobbies are jogging and doing yoga. When I have free time, I like to go jogging to the park. I think jogging is really fun as a hobby. Also, I do yoga almost every day. I feel so relaxed when I'm doing it. Yoga is a great way for me to relieve my stress.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[마무리] Well, I think that's it. Maybe I can tell you more about myselft in future questions. Thank you!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;편의상 4가지 카테고리로 나눠두었지만, 실제 답변시에는 저것들을 다 이어서 말하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;답변은 가능한 길고 풍부하게&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모든 질문에 대한 답변은 가능한 길고 풍부하게 하는 것이 좋다. 예컨대, 설문에서 취미 활동으로 음악 감상을 골랐고, 이에 대한 관련 질문으로 좋아하는 뮤지션을 물어보는 질문이 나올 수 있다. 이 경우 단순히 &quot;저는 IU를 좋아해요. IU는 예쁘고, 노래를 잘해요.&quot; 라는 질문 보다는 &quot;제 최애 가수는 IU에요. 그녀는 아주 재능이 많아요. 그녀의 노래를 들을 때면 마음이 편해지는 걸 느껴요. 또한 그녀의 음악들은 따라부르기 쉬운 리듬과 가사를 갖고 있어요.&quot;와 같이 좀 더 풍부하게 답변하는 것이 좋다. 이를 영어로 비교해보면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;I like IU. IU is pretty and she sings well.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;My all time favorite singer is IU. I think she is so talented. I feel so realxed when I listen to her voice. Moreover her songs have catchy rythm and lyrics. That's why I like her so much.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;적절한 paraphrasing을 사용하자 (반복어 사용 자제)&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;반복된 표현은 지루한 느낌을 준다. 특히나, &lt;b&gt;오픽은 외운 티가 나는 답변을 가장 싫어한다&lt;/b&gt;. 위의 예시에서처럼 좋아하는 가수나 음식에 대한 질문의 경우에도 단순히 &quot;I like&quot;를 반복적으로 사용하는 것을 피해야 한다. &quot;My all time favorit ~ is&quot;, &quot;I also really like ~&quot;, &quot;Doing ~ is one of my favorite thing when I have free time&quot;, &quot;I'm addicted to ~&quot; 이런식으로 좋아한다는 표현도 굉장히 다양하게 말할 수 있다. 적절하게 &lt;b&gt;paraphrasing&lt;/b&gt;을 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;객관적인 묘사보다는 내가 느낀 감정 위주로 답변하자&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;객관적인 묘사를 영어로 하는 것은 어렵다. 반면 나의 감정에 대해 묘사하는 것은 정해진 답이 있는 것도 아니고 떠올리기도 훨씬 쉽다.&lt;/b&gt; 예컨대, 콘서트 방문 경험에 대해 말할 때, &quot;해당 콘서트에는 대략 몇 명 정도의 굉장한 관중들이 모여있었고, 스테이지는 어떻게 되어있었다. 그날 날씨는 어땟고, 가수 라인업은 어떠했다&quot;보다도 &quot;그 콘서트를 보고 나는 너무 행복했다. 내가 좋아했던 가수도 나왔고, 관중들은 모두 환호했다. 나는 거기서 생동감을 느꼈고, 내가 좋아했던 가수의 노래를 들을 땐 너무 즐거웠다.&quot;라는 식으로 답변하는 편이 훨씬 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;마찬가지로, 좋아하는 식당에 대해서 물어볼 때에도 &quot;해당 식당은 어디에 있고, 내부 구조는 어떠하다. 인테리어가 예뻐서 좋고, 거기에 갈 때마다 점원들이 나를 친절하게 맞아주어서 자주 간다.&quot;보다도 &lt;b&gt;&quot;My favorite restaurant is Pizza hut. It's near my house. I can't live without Pizza and especially I love Pizza hut's pepperoni pizza. I visited there last week and I will go there this weeked also.&quot;&lt;/b&gt;와 같이 내가 느낀 감정, 나의 생각을 위주로 답변을 구성하는 것이 훨씬 생각하기도 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;어려운 문제 대처법 (중요!!)&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아무리 열심히 준비를 했다고 한들 답변하기 어려운 문제는 분명 나올 수 있다. 하지만, 그런 문제라고 해서 답변을 안하고 그냥 넘어가면 안된다. &lt;b&gt;중요한 것은 어떻게든 주절주절 답변을 하고나서 다음 문제로 넘어가는 것이다.&lt;/b&gt; 여기서는 그 전략 세 가지를 소개한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. 투덜대기 전략&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;말그대로 문제가 너무 어렵다고 Ava에게 투덜대는 전략이다. 이렇게 투덜대면서 뭐라도 말하는 것이 안하고 문제를 스킵하는 것보다 낫다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Seriously? Are you kidding?&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Oh, wow! This is a very hard question becuase I've never thought about it&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Why do you ask me such a hard question, Ava?&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I have to say that's a really complicated question&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Oh my god...the history of the banks in our country? Are you kidding?&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;마지막 문장처럼 질문에서 나온 말(우리나라 은행의 역사)을 반복하면서 투덜대는 것도 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. 모른다는 말을 장황하게 하는 전략&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;실제로 내가 했던 전략이다. 모르는 문제가 나왔다고 해서 절대 호들갑 떨면 안된다! 난처해하면서 &quot;Oh....well...oh...I'm sorry...I'm sorry..&quot;하지 말고 &lt;b&gt;당당하게 모른다고 말해야 한다&lt;/b&gt;. 오픽은 기계와 대화하지만 실제 채점은 사람이 들어보고 한다. 그렇기 때문에 사람이 듣기에 영어를 잘하는 것처럼 보이는 것은 매우 중요하다. &lt;b&gt;말을 더듬거나 당황하면서 sorry를 남발하면 듣는 평가자로 하여금 이 사람이 영어를 잘하는 사람이라는 생각을 갖기 어렵게 만든다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;많은 사람들이 질문에 대해서 &quot;모른다&quot;라고 답변하면 감점이 될거라고 생각하는데 그렇지 않다. 실제로 오픽은 모든 답변에 대해 아주 자세하게 영어로 표현하는 것을 채점하는 시험이 아니라, 영어로 회하를 하는 수준을 측정하는 시험이다. 오히려 모든 질문에 대해 해당하는 모든 경험이 존재하고, 모든 지식을 알고 있는게 더 이상하다. 그러니 &lt;b&gt;당황하지 말고 &quot;모른다&quot;는 말을 최대한 장황하고 풍부하게 설명하자!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 때 사용할 수 있는 표현들은 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I'm sorry, but I think I should skip this question because I don't know what to say.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I mean... I have no idea about this topic.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;So I'll try my best to answer your next question&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well...That's a very hard question...&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Honestly, I've never thought about it at all.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I'm not familiar with this topic&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I think I'm totally lost&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I'm sorry, I couldn't answer your question this time, but please give me a chance to answer your next question&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Umm... I don't know...I've never had an experience like that&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Seriously I don't think I have faced a problem like that&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Since I don't have an experience related to this topic, I'll just move on to your next question&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well... you know, I don't want to misinform you.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I have no idea about this because I hardly read the news these days. I mean, I've been so busy lately. So, I can't think of any issues related to this topic.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;나의 경우 지형을 물어보는 문제에 대해 실제로 아래와 같이 답변하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Oh! the geography of ~? Are you kidding Ava? I should say this is a really hard question. Well...let me think about it....Actually I have no idea because I'm not that interested in geographcial feautres so I don't know much about it. Moreover, you know, I don't want to misinform you. So if it's okay with you can I just skip this question and move on to your next question? I will do my best to answer your next question.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;3. 다른 방향으로 유도하기 전략&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 방법은 질문한 문제에 대해 답하기 어려울 때 내가 답하기 쉬운 조금 비슷한 방향으로 바꿔서 대답하는 방법이다. 예를 들어 &quot;너희 나라에서 은행의 과거와 현재에 대해서 비교해서 답해봐라&quot;라는 질문에 대해 &quot;과거의 경우 내 은행업무는 주로 부모님이 해주셔서 잘모르겠어. 대신 현재에 대해서 말해줄게&quot;와 같은 식이다. 아래와 같이 답변할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;So if it's okay with you I'd like to talk about ~ instead&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Since I don't know much about A, I'll just talk about B instead&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Filler 많이 준비해두기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Filler란 말 중간중간에 채워주는 추임새 같은 것이다. 이런 filler를 적절히 사용하면 듣기에 훨씬 유창해보인다. 말이 막힐 때 그대로 적막이 흐르는 것보다는 이런 &lt;b&gt;filler를 사용해서 말이 끊기지 않고 이어지도록&lt;/b&gt; 하면 된다. 아래와 같은 filler를 많이 준비해두고 자주 사용해주자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Um...&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well...&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Recently...&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well... you know&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well.. let me think&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Thing is....&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Could you give me some time to think about it?&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Okay...well, I think I need some time to think about it&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;시작과 마무리 문장은 확실하게 하자&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;문제가 끝났다고 바로 답변하거나, 내 답변이 끝났다고 바로 다음 문제로 넘어가는 것보다는 말의 시작과 끝을 분명하게 해주는 것이 좋다. 경계가 뚜렷해져서 훨씬 깔끔하고 내가 말할 내용들을 정돈해볼 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. 시작 문장 (확실한 주제어 말해주기, 무엇에 대해 말할건지)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;As for ~&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Regarding ~&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;When it comes to ~&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Let me tell you about my recent experience about ~&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well.. I can probably tell you about ~&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;I would say ~&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. 마무리 문장&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Well.... I think that's all about ~. Thank you!&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;That's it. I think that's all about my experience&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;All these are the reasons that I like IU&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;다양한 접속사 사용하기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;생각보다 회화에서 적절한 접속사로 이어주는 것이 어렵다. 사실 'and'를 가장 많이 사용할텐데, 'and'만 남용하기보단 접속사도 아래와 같이 다양하게 사용하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;In addition&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Also&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Moreover&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Furthermore&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&quot;Besides&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;To stay healthy I do a lot of things. First, I eat healthy food &lt;b&gt;and&lt;/b&gt; I usually cook at home. &lt;b&gt;In addition to food&lt;/b&gt;, I &lt;b&gt;also&lt;/b&gt; take health supplement like vitamin C. &lt;b&gt;Besides&lt;/b&gt; these, I do regular exercise.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모두 좋은 결과가 있기를!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>영어</category>
      <category>opic</category>
      <category>오픽</category>
      <category>오픽 AL</category>
      <category>오픽 IH</category>
      <category>오픽 강의</category>
      <category>오픽 공략</category>
      <category>오픽 시험</category>
      <category>오픽 잘보는 법</category>
      <category>오픽 전략</category>
      <category>토익 스피킹</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/396</guid>
      <comments>https://otugi.tistory.com/396#entry396comment</comments>
      <pubDate>Sun, 24 Sep 2023 15:12:44 +0900</pubDate>
    </item>
    <item>
      <title>최신 NLP 연구 트렌드(ACL2023 회고록)</title>
      <link>https://otugi.tistory.com/395</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;캐나다 토론토에서 ACL2023이 개최되었다. &lt;s&gt;7월에 다녀왔는데 귀찮아서 미루고 미루다 한달이 지나서야 후기를 쓰는 나...&lt;/s&gt; 이러다간 내용 다 까먹어버릴까봐 무서워서 얼른 호다닥 쓴다 ㅋㅋㅋ(하...그나저나 캐나다 너무 좋았다...헤으응...또 가고싶...) 이 글에선 ACL2023에서 본 것들을 토대로 최신 NLP 연구 동향에 대해 소개해보고자 한다. 이번 학회에서는 굉장히 많은 토픽들이 다루어졌는데 그 중에서 &lt;b&gt;사람들이 많이 몰리는 세션&lt;/b&gt;과 &lt;b&gt;해당 주제로 많은 페이퍼가 나온 토픽&lt;/b&gt;과 &lt;b&gt;이전에는 없었다가 새롭게 등장한 토픽&lt;/b&gt;들을 기준으로 선정하여 소개하고자 한다. 아무래도 그 세 가지 위주로 보는 것이 좀 더 유의미하지 않을까 싶다. 덧붙이자면 모든 토픽에 대해 세세하게 설명하기 보다는 그저 내가 보았던 것들 위주로 전반적인 경향을 가볍게 훑고 핵심을 언급하면서 설명할 것이다. 그러니 그냥 &quot;아~ 이번 ACL 학회에서는 이러한 것들이 다루어졌구나~&quot;하는 정도로 가볍게 보면 될 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Large Language Model (LLM)&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ChatGPT와 함께 LLM 분야가 많은 각광을 받고 있다. 이번 학회에서도 역시 많은 페이퍼들이 나왔다. &lt;b&gt;새로운 LLM을 제안&lt;/b&gt;하는 페이퍼들도 정말 많았고, 이러한 &lt;b&gt;LLM을 다양하게 활용하는 방법&lt;/b&gt;들에 대한 주제들도 많았다. 예컨대, &lt;b&gt;human evaluation을 LLM으로 대체&lt;/b&gt;하거나 data labeling의 &lt;b&gt;annotator&lt;/b&gt;로 사용하거나 혹은 LLM을 사용해 &lt;b&gt;data augmentation&lt;/b&gt;을 하는 주제들도 많이 보였다. 눈여겨볼 부분은 LLM의 활용에 대한 주제들이 심심찮게 보였다는 점이다. LLM을 이용해 기존의 인간 노동력이 필요하던 작업이나 rule-based로 복잡하게 처리되던 작업들을 쉽고 빠르게 처리하려는 움직임이 보였다. 앞으로도 LLM 분야는 계속해서 많은 발전이 있을 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Multilingual &amp;amp; Crosslingual&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;multilingual과 crosslingual과 관련된 세션에 사람들이 정말 많이 몰렸다. 오히려 conversational AI 세션보다도 더 많이 몰려서 놀랐다. 개인적인 생각으로는, &lt;b&gt;LLM이 등장하고 어느 정도 좋은 성능들을 보이는 것이 알려졌으니 이것을 모든 언어에서 잘 작동하도록 해서 많은 사람들이 사용할 수 있게 하려는 움직임&lt;/b&gt;으로 생각된다. 어찌보면 당연한 것 같다. LLM의 학습데이터는 거의 대부분이 영어인 경우가 많다. multilingual model이라고 해도 영어에서의 성능이 가장 높게 나온다. 실제로 ChatGPT에게 같은 문맥의 질문을 영어와 한국어로 해서 비교해보면 답변의 퀄리티가 차이나는 경우가 종종 있다. 이처럼 데이터의 bias에 의한 성능상의 차이를 극복하려는 시도들이 많이 보였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그 외 부가적인 것으로는 multilingual과 crosslingual related topic이 관심을 끌면서 기존의 conventional task인 machine trainslation이 다시 각광을 받기 시작했다는 점이다. 또한 소수가 사용하는 언어들에 대한 데이터셋 구축과 같이 점차 &lt;b&gt;linguistic diversity&lt;/b&gt;를 추구하려는 방향으로 나아가고 있다. 아! 참고로 한국어의 경우 multilingual dataset에서 타 언어 대비 굉장히 낮은 성능을 보인다....거의 일본어와 한국어가 성능 리포트에서 거의 밑바닥에 있었다...multilingual POS tagging task에선 영어와 비교해 한국어가 거의 20-30 정도의 스코어 차이가 났다. 아무래도 구축된 양질의 데이터셋이 영어 대비 적기도 하고, 형태소나 조사 같은 언어구조적인 복잡성 때문에 이러한 결과가 생긴 것 같다. 가까운 미래에 AI 기술에서의 격차를 줄이려면 우리 나라에서의 자체적인 한국어AI에 대한 연구가 많이 이루어져야 할 것 같다. 기본적으로 ChatGPT와 같이 영어로 학습한 지식을 기반으로 한 답변을 한국어로 번역해 알려주는 시스템은 한국어 고유의 특징을 반영할 수 없기 때문이다(예컨대, 높임말 같은 politeness). 실제로 그 나라의 언어는 그 나라의 문화를 반영한다는 생각으로 언어와 문화 간의 correlation을 수치적으로 분석하려는 토픽도 보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;More Human-like AI&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제는 단순히 기계적인 AI를 넘어서 &lt;b&gt;좀 더 사람같은 AI 시스템&lt;/b&gt;을 만드는 것 또한 중요해졌다. 이와 같은 맥락에서 이번 학회에서도 human-like AI에 대한 주제들이 많이 보였다. speaker intention detection이라고 해서 단순히 user의 질문에 답변만 하는 것이 아니라 화자의 의도를 분석해서 답변을 하는 연구들이 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;또한, LLM의 등장으로 model이 수행해야 할 task들이 점차 복잡, 다양해지고 있다. conventional task들처럼 format이 항상 일정하지도 않고, 단순히 정답 label로 학습만 한다고 해서 맞추기 어려운 문제들이 등장하고 있다. 이에 따라 기존의 단순한 task들(ex. classification, regression)보다 훨씬 복잡한 reasoning과 같은 task에서 좋은 성능을 내기 위한 연구들이 많았다. 음....아 그리고 흥미로웠던 건 humor를 이해하는 LLM에 대한 연구도 있었다 ㅋㅋㅋ(재밌어보여서 듣고 싶었는데 해당 포스터에 사람들이 너무 많이 몰려서 보지를 못했다 ㅜㅜ)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Moral &amp;amp; Ethics in AI&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;AI에서 윤리나 도덕과 관련된 문제들이 야기되면서 해당 주제 관련 페이퍼들이 많이 보였다. 아예 해당 세션이 따로 있을 정도였다. 아무래도 요즘 가장 핫한 주제인만큼 이쪽 세션에도 사람들이 정말 많이 몰렸다. 학계에서도 공통된 의견 중 하나는 요즘 들어 빅테크 기업들이 AI reasearch 분야에서 거의 독점적으로 연구를 이끌어가고 있다는 것이었다. 관련해서 통계적으로 분석한 페이퍼도 이번 학회에 있었다. AI 분야는 computing resource 때문에 어쩔 수 없이 돈과 맞물려 발전하게 되어있고, 모델이 점차 커짐에 따라 이렇나 격차는 더 가속화 되어가고 있다. 때문에 이제는 대학 레벨에서 할 수 있는 연구와 기업 레벨에서 할 수 있는 연구가 점차 나뉘어지고 있는 실정이다. (사실 연구실에서 교수님과 선후배들과 이러한 이야기를 정말 많이 나누었는데...세계적으로 다들 비슷하게 느끼고 있는 것 같다) dataset에서의 bias에 대한 연구들도 많았다. language bias, gender bias나 social minority bias로 모델에 야기되는 문제들과 같은 것들.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Moral과 Ethic 관련된 주제의 페이퍼들이 많이 나오는 이유는 아무래도 이제 어느 정도 AI의 발전이 saturated되었다는 생각에서 비롯된 것 같다. 예컨대, 우리나라도 60년대에는 맹목적인 목표지향적 경제 성장이 목표였지만 그 목표를 어느 정도 이루고 나자 웰빙, 워라밸과 같은 단어들이 등장하였다. 이처럼 모든 기술의 발전은 처음엔 성능 지향적(performance-oriented)인 발전이 주를 이루다가 어느 순간 &lt;b&gt;가치 지향적(value-oriented)&lt;/b&gt;인 발전으로 옮겨가게 되어있다. 아마도 그러한 맥락에서 도덕이나 윤리와 관련된 주제들이 각광을 받는게 아닐까 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Parameter Efficient Training Method&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;PEFT(Parameter Efficient Fine Tuning)과 같이 &lt;b&gt;training cost를 획기적으로 줄일 수 있는 기법&lt;/b&gt;들에 대한 연구가 이번 학회에서 많이 보였다. 아무래도 모델이 점차 거대화되어 가고 있는 시점에 실질적, 경제적인 차원에서 중요한 문제가 되어서 그런 것 같다. 얼마 전 학교에 방문한 한 환경공학 교수님의 특강에서 들었는데 AI가 등장하면서 데이터센터 같은 곳의 서버GPU 때문에 탄소배출량이 증가하였고, 실제로 이것이 점점 더 증가하고 있는 추세라고 한다. 비단 이런 이유 뿐만 아니라 실제로 요즘 등장하는 거대 모델들은 그 엄청난 파라미터 수 때문에 학습시키는데 몇 시간 단위가 아닌 몇일 길게는 한 두달까지의 시간이 걸리기도 한다. 이러한 비효율적인 문제를 해결하기 위해서라도 Parameter Efficient Training Method에 대한 연구가 필요한 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;NLP + Health care&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;NLP와 health care를 접목한 페이퍼들도 전과 달리 많이 보였다. 이것도 아예 하나의 세션이 따로 마련되어 있어서 health care 분야에서 NLP를 접목한 페이퍼들을 묶어서 설명하기도 하였다. 내가 보았던 주제들은 상담사와의 메신저 히스토리를 데이터로 사용해 mental disorder를 detection하는 것과 mental care에 도움을 주는 챗봇에 대한 연구였다. 아무래도 NLP 분야가 언어와 관련된 분야이다보니 주로 physical health보다는 말에서 드러나는 mental health 관련 연구들이 많은 것 같다. Health care분야는 AI에서도 예나 지금이나 정말 많은 관심을 받고 있는 분야인데, 먼 미래에 AI 닥터가 정말 실현될 수 있을지 나도 너무 궁금하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;High quality generation&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제 LM은 단순한 문장을 generation하는 것을 넘어서 long story를 generation하기도 한다. 이처럼 점차 많은 양의 text generation을 수행함에 따라 좀 더 고도화된 generation을 하는 것이 중요해졌다. 짧은 단문보다 긴 글을 생성할 때에는 서두의 정보를 잊어버리거나 잘못된 문장을 생성할 확률이 더 높아지기 때문이다. 이에 따라 long text에서 &lt;b&gt;coherence&lt;/b&gt;를 유지하도록 하는 method에 대한 연구가 등장하였다. 또한 open-ended text generation에서 단순한고 뻔한 응답보다는 좀 더 &lt;b&gt;context를 잘 반영&lt;/b&gt;하고 consistent한 답변을 generation하는 연구도 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Evaluation&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;LLM과 instruction-following task의 등장으로 이제는 model이 수행해야하는 task들이 더 복잡해졌다. 예컨대, 개와 고양이를 구분하는 단순한 문제에서 지금은 &quot;층간소음 경고문을 작성해줘&quot;, &quot;여름철 발리 휴양지 10가지만 추천해줘&quot;와 같은 고정되지 않은 양식의 task들을 수행해야만 한다. 이에 따라, &lt;b&gt;점점 복잡해지는 task들에 대한 evaluation method들에 대한 연구&lt;/b&gt;가 많이 등장하고 있다.&amp;nbsp; 내 생각에 이러한 연구들은 대부분 두 가지 측면에서 이루어지는 것 같았다. &lt;b&gt;1)기존의 previous metric의 단점을 보완하는 metric 2)사람의 관점을 잘 반영하는 metric.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;evaluation 분야도 앞으로 점점 더 많은 페이퍼들이 등장할 것으로 생각된다. 모델의 성능을 수치적으로 report할 수 있는 수단이고 학계도 점점 기존의 metric들이 현재 등장하는 모델들의 성능을 측정하기에 한계가 있다는 사실을 인지하고 있기 때문이다. 때문에 기존의 단순하고 단편적인 측면을 평가하는 automatic metric 대신 GPT4 evaluation을 많이 하기도 한다. 실제로 GPT4가 human evaluation을 대체할 수 있는지에 대한 페이퍼도 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Better Prompt Design&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;LLM의 등장으로 prompt의 중요성도 대두되고 있다. 실제로 prompt에 따라 모델이 생성하는 답변의 퀄리티가 달라지고 hallucination 같은 문제가 발생하기도 한다. 아무리 좋은 도구가 있더라도 제대로 사용할 수 있는 방법을 알아야 하는 것이다. 이에 따라 &lt;b&gt;더 나은 prompt design 전략&lt;/b&gt;에 대한 페이퍼들이 많이 나왔다. 그 중 가장 많이 보였던 것은 &lt;b&gt;Chain of Thought(CoT)&lt;/b&gt;였다. 간단히 말하자면, reasoning과 같은 복잡한 문제에서 인풋 프롬프트에 few-shot learning과 같이 예시를 주는 것이다. 이 때 예시에 해당 문제를 해결하는 논리적인 풀이 과정이 포함되어 있어야 한다. 그리고 마지막으로는 Let's think step by step이라는 trigger sentence를 넣어주는 것이다. 이러한 방식의 목적은 모델에게 단순히 답이 아닌 답을 도출해내는 과정을 학습시킨다는 것이다. 관련해서 더 자세한 내용은 &lt;a href=&quot;https://tech.kakaoenterprise.com/188&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;카카오에서 정리해둔 링크&lt;/a&gt;를 참고하기 바란다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230820_155006572.jpg&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;1411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hn8RL/btsrB0s3Vqk/5HDnrOlhBWfCTwL1dvyLI1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hn8RL/btsrB0s3Vqk/5HDnrOlhBWfCTwL1dvyLI1/img.jpg&quot; data-alt=&quot;ACL2023 학회장 로비&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hn8RL/btsrB0s3Vqk/5HDnrOlhBWfCTwL1dvyLI1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHn8RL%2FbtsrB0s3Vqk%2F5HDnrOlhBWfCTwL1dvyLI1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1058&quot; height=&quot;1411&quot; data-filename=&quot;KakaoTalk_20230820_155006572.jpg&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;1411&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ACL2023 학회장 로비&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230820_155019801.jpg&quot; data-origin-width=&quot;1411&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mKSNU/btsrysjgcqg/GvIxbWMrQKGl7X8LdD4rWk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mKSNU/btsrysjgcqg/GvIxbWMrQKGl7X8LdD4rWk/img.jpg&quot; data-alt=&quot;ACL2023 학회장 호텔의 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mKSNU/btsrysjgcqg/GvIxbWMrQKGl7X8LdD4rWk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmKSNU%2Fbtsrysjgcqg%2FGvIxbWMrQKGl7X8LdD4rWk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1411&quot; height=&quot;1058&quot; data-filename=&quot;KakaoTalk_20230820_155019801.jpg&quot; data-origin-width=&quot;1411&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ACL2023 학회장 호텔의 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230820_155030461.jpg&quot; data-origin-width=&quot;1411&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4rseq/btsrBO0G97g/AzcO7iAjGTeeytNcVDzMQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4rseq/btsrBO0G97g/AzcO7iAjGTeeytNcVDzMQ1/img.jpg&quot; data-alt=&quot;튜토리얼이었나 메인 컨퍼런스 세션이었나 잘 기억나진 않지만 한컷...ㅋㅋㅋ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4rseq/btsrBO0G97g/AzcO7iAjGTeeytNcVDzMQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4rseq%2FbtsrBO0G97g%2FAzcO7iAjGTeeytNcVDzMQ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1411&quot; height=&quot;1058&quot; data-filename=&quot;KakaoTalk_20230820_155030461.jpg&quot; data-origin-width=&quot;1411&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;튜토리얼이었나 메인 컨퍼런스 세션이었나 잘 기억나진 않지만 한컷...ㅋㅋㅋ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230820_155132814.jpg&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;1411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dj6Kuy/btsrCuOb2nI/a2YJkW9PZDZIOiLzCNsCLk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dj6Kuy/btsrCuOb2nI/a2YJkW9PZDZIOiLzCNsCLk/img.jpg&quot; data-alt=&quot;포스터 세션&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dj6Kuy/btsrCuOb2nI/a2YJkW9PZDZIOiLzCNsCLk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdj6Kuy%2FbtsrCuOb2nI%2Fa2YJkW9PZDZIOiLzCNsCLk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1058&quot; height=&quot;1411&quot; data-filename=&quot;KakaoTalk_20230820_155132814.jpg&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;1411&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;포스터 세션&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>NLP</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/395</guid>
      <comments>https://otugi.tistory.com/395#entry395comment</comments>
      <pubDate>Sun, 20 Aug 2023 15:55:32 +0900</pubDate>
    </item>
    <item>
      <title>아나콘다 GPU 환경 설정(python3.9, torch1.11.0)</title>
      <link>https://otugi.tistory.com/394</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아나콘다 설치 방법은 여러 곳에서 찾아볼 수 있으니 생략하겠다. GPU를 사용하는 머신러닝을 위해서는 환경설정이 중요하다. 아나콘다를 이용해 환경 세팅을 해주어야 하는데 파이썬, 파이토치, 쿠다 버전을 맞추기가 까다롭다. 각 버전별로 호환이 되는 것들이 정해져있어서 다른 버전으로 다운받았다가는 싹 다 엎고 재설치를 해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기서는 python3.9에 pytorch를 설치하여 GPU 환경을 구축하는 방법을 소개한다. 먼저 아래와 같은 커맨드로 python3.9를 사용하는 콘다 가상환경을 생성한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688301815410&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create -n [환경이름] python=3.9&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;가상환경이 만들어졌으면 아래 커맨드로 해당 가상환경을 활성화시킨다.&lt;/p&gt;
&lt;pre id=&quot;code_1688301964406&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda activate [환경이름]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그 후 아래 커맨드로 python3.9에 호환이 되는 torch, cuda를 비롯한 패키지들을 설치한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688301856620&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda install pytorch==1.11.0 torchvision==0.12.0 torchaudio==0.11.0 cudatoolkit=11.3 -c pytorch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>anaconda</category>
      <category>conda</category>
      <category>cuda</category>
      <category>cudatoolkit</category>
      <category>GPU환경설정</category>
      <category>PYTHON</category>
      <category>pytorch</category>
      <category>딥러닝 환경설정</category>
      <category>아나콘다</category>
      <category>쿠다</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/394</guid>
      <comments>https://otugi.tistory.com/394#entry394comment</comments>
      <pubDate>Sun, 2 Jul 2023 21:45:21 +0900</pubDate>
    </item>
    <item>
      <title>[사이드 프로젝트] 만개의 레시피 크롤링(한식 정보 크롤링)</title>
      <link>https://otugi.tistory.com/393</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;학교 수업의 프로젝트 일환으로 외국인들에게 한식을 소개하는 어플을 제작했다. 해당 프로젝트에서 내가 담당했던 부분은 데이터 파트를 구축하는 일이었는데, 이를 위해 만개의 레시피를 크롤링하는 부분을 구현하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;식약처 API(첫번째 시도)&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;처음엔 식약처에 제공하는 API를 사용하였다. 해당 링크는 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;http://www.foodsafetykorea.go.kr/api/openApiInfo.do?menu_grp=MENU_GRP31&amp;amp;menu_no=661&amp;amp;show_cnt=10&amp;amp;start_idx=1&amp;amp;svc_no=COOKRCP01&quot;&gt;http://www.foodsafetykorea.go.kr/api/openApiInfo.do?menu_grp=MENU_GRP31&amp;amp;menu_no=661&amp;amp;show_cnt=10&amp;amp;start_idx=1&amp;amp;svc_no=COOKRCP01&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685776036024&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;데이터활용서비스&quot; data-og-description=&quot;설명 속성정보 일련번호 , 메뉴명 , 조리방법 , 요리종류 , 중량(1인분) , 열량 , 탄수화물 , 단백질 , 지방 , 나트륨 , 해쉬태그 , 이미지경로(소) , 이미지경로(대) , 재료정보 , 만드는법_01 , 만드는&quot; data-og-host=&quot;www.foodsafetykorea.go.kr&quot; data-og-source-url=&quot;http://www.foodsafetykorea.go.kr/api/openApiInfo.do?menu_grp=MENU_GRP31&amp;amp;menu_no=661&amp;amp;show_cnt=10&amp;amp;start_idx=1&amp;amp;svc_no=COOKRCP01&quot; data-og-url=&quot;http://www.foodsafetykorea.go.kr/api/openApiInfo.do?menu_grp=MENU_GRP31&amp;amp;menu_no=661&amp;amp;show_cnt=10&amp;amp;start_idx=1&amp;amp;svc_no=COOKRCP01&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.foodsafetykorea.go.kr/api/openApiInfo.do?menu_grp=MENU_GRP31&amp;amp;menu_no=661&amp;amp;show_cnt=10&amp;amp;start_idx=1&amp;amp;svc_no=COOKRCP01&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.foodsafetykorea.go.kr/api/openApiInfo.do?menu_grp=MENU_GRP31&amp;amp;menu_no=661&amp;amp;show_cnt=10&amp;amp;start_idx=1&amp;amp;svc_no=COOKRCP01&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;데이터활용서비스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;설명 속성정보 일련번호 , 메뉴명 , 조리방법 , 요리종류 , 중량(1인분) , 열량 , 탄수화물 , 단백질 , 지방 , 나트륨 , 해쉬태그 , 이미지경로(소) , 이미지경로(대) , 재료정보 , 만드는법_01 , 만드는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.foodsafetykorea.go.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 링크에 접속해보면 아래와 같은 URL 요청 방식이랑 요청 인자들에 대한 설명이 나온다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;999&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwAgae/btsiuMJ1Qhk/ERdKTDwo20fuVcA1zGjXuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwAgae/btsiuMJ1Qhk/ERdKTDwo20fuVcA1zGjXuK/img.png&quot; data-alt=&quot;식약처 한식 API 요청주소 및 인자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwAgae/btsiuMJ1Qhk/ERdKTDwo20fuVcA1zGjXuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwAgae%2FbtsiuMJ1Qhk%2FERdKTDwo20fuVcA1zGjXuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1326&quot; height=&quot;999&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;999&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;식약처 한식 API 요청주소 및 인자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 API를 통해 요청하면 아래와 같은 정보들을 얻을 수 있다. 더 많으 정보들에 대한 설명은 위 링크를 통해 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;1011&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqX8F4/btsit0Iyr06/yFfVflokgD8X0BHc3f4CN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqX8F4/btsit0Iyr06/yFfVflokgD8X0BHc3f4CN1/img.png&quot; data-alt=&quot;식약처 한식 API 출력항목&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqX8F4/btsit0Iyr06/yFfVflokgD8X0BHc3f4CN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqX8F4%2Fbtsit0Iyr06%2FyFfVflokgD8X0BHc3f4CN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;959&quot; height=&quot;1011&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;1011&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;식약처 한식 API 출력항목&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그런데 생각보다 식약처에서 제공하는 API에서 커버하는 한식의 종류가 다양하지 않았다. 따라서, 다른 방법을 찾아보았다. 좀 더 많은 종류의 한식 정보를 제공할 수 있는 방법으로 나는 만개의 레시피라는 한식 검색 사이트를 크롤링하여 데이터를 구축하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만개의 레시피 크롤링&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만개의 레시피는 사용자들이 레시피를 등록할 수 있는 레시피 검색 사이트이다. 여러 종류의 음식들을 다루고 있고, 확실히 식약처 API보다 많은 종류의 한식들에 대한 정보를 담고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAQkbp/btsis6W5hLV/56knqJ9IoVFsZ0W12XZxz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAQkbp/btsis6W5hLV/56knqJ9IoVFsZ0W12XZxz1/img.png&quot; data-alt=&quot;만개의 레시피 메인 페이지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAQkbp/btsis6W5hLV/56knqJ9IoVFsZ0W12XZxz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAQkbp%2Fbtsis6W5hLV%2F56knqJ9IoVFsZ0W12XZxz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1126&quot; height=&quot;673&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;만개의 레시피 메인 페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;What to select?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다음으로 봉착한 문제는 어떤 음식을 선택해서 유저에게 보여줄 것인지였다. 가령, 김치찌개라고 하면, 참치김치찌개, 묵은지 김치찌개, 돼지고기 김치찌개와 같이 들어가는 재료에 따라 여러 종류가 있다. 이 중 우리는 가장 보편적이고 대중적인 음식을 선택해 해당 음식의 레시피와 재료들을 보여주기로 하였다. 이를 위해, &quot;김치찌개&quot;라고 검색하였을 때, 추천순으로 정렬한 뒤 가장 상단의 가장 첫번째 메뉴를 크롤링하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kFlKs/btsisPnypZq/9oks2KR1nDRXEf24qFuML0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kFlKs/btsisPnypZq/9oks2KR1nDRXEf24qFuML0/img.png&quot; data-alt=&quot;음식 선정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kFlKs/btsisPnypZq/9oks2KR1nDRXEf24qFuML0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkFlKs%2FbtsisPnypZq%2F9oks2KR1nDRXEf24qFuML0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1510&quot; height=&quot;576&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;음식 선정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;What to crawl?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다음으로는 어떠한 정보들을 크롤링할 것인지를 선택하여야 하는데, 특정 음식을 클릭하면 아래와 같이 재료와 레시피에 대한 정보를 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bouxLd/btsivRjNpM0/K6Tpcd0J6qNdG5B97wDr3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bouxLd/btsivRjNpM0/K6Tpcd0J6qNdG5B97wDr3K/img.png&quot; data-alt=&quot;재료 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bouxLd/btsivRjNpM0/K6Tpcd0J6qNdG5B97wDr3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbouxLd%2FbtsivRjNpM0%2FK6Tpcd0J6qNdG5B97wDr3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;910&quot; height=&quot;480&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;재료 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xOwbL/btsitA4KeNx/zH466DAFEEP9u3D3pQNXJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xOwbL/btsitA4KeNx/zH466DAFEEP9u3D3pQNXJ0/img.png&quot; data-alt=&quot;레시피 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xOwbL/btsitA4KeNx/zH466DAFEEP9u3D3pQNXJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxOwbL%2FbtsitA4KeNx%2FzH466DAFEEP9u3D3pQNXJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;571&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;레시피 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우리는 재료와 레시피, 두가지 정보를 크롤링해 유저에게 보여주기로 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;크롤링 구현&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1685776640465&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import requests, json
from bs4 import BeautifulSoup

def food_info(name):
    '''
    This function gives you food information for the given input.

    PARAMETERS
        - name(str): name of Korean food in Korean ex) food_info(&quot;김치찌개&quot;)
    RETURN
        - res(list): list of dict that containing info for some Korean food related to 'name'
            - res['name'](str): name of food
            - res['ingredients'](str): ingredients to make the food
            - res['recipe'](list[str]): contain recipe in order
    '''
    url = f&quot;https://www.10000recipe.com/recipe/list.html?q={name}&quot;
    response = requests.get(url)
    if response.status_code == 200:
        html = response.text
        soup = BeautifulSoup(html, 'html.parser')
    else : 
        print(&quot;HTTP response error :&quot;, response.status_code)
        return
    
    food_list = soup.find_all(attrs={'class':'common_sp_link'})
    food_id = food_list[0]['href'].split('/')[-1]
    new_url = f'https://www.10000recipe.com/recipe/{food_id}'
    new_response = requests.get(new_url)
    if new_response.status_code == 200:
        html = new_response.text
        soup = BeautifulSoup(html, 'html.parser')
    else : 
        print(&quot;HTTP response error :&quot;, response.status_code)
        return
    
    food_info = soup.find(attrs={'type':'application/ld+json'})
    result = json.loads(food_info.text)
    ingredient = ','.join(result['recipeIngredient'])
    recipe = [result['recipeInstructions'][i]['text'] for i in range(len(result['recipeInstructions']))]
    for i in range(len(recipe)):
        recipe[i] = f'{i+1}. ' + recipe[i]
    
    res = {
        'name': name,
        'ingredients': ingredient,
        'recipe': recipe
    }

    return res&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 코드는 인자로 음식명을 넘겨주었을 때, 해당 음식에 대한 정보들을 return해주는 함수이다. 구체적으로는 음식명, 재료, 레시피의 세가지 정보를 딕셔너리 타입으로 return해준다. 크롤링은 beautifulsoup 라이브러리를 통해 구현하였다.(해당 라이브러리는 pip install bs4 커맨드로 다운로드할 수 있다.) 함수에 대한 자세한 설명은 코드 내의 주석에 자세히 기록해두었으니 참고하길 바란다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;크롤링 결과&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 함수를 통해 &quot;김치찌개&quot;라는 음식에 대한 정보를 추출하면 아래와 같은 결과가 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FFXes/btsiurzm5Ol/KWOGXisUHVx2MXIYqDgPU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FFXes/btsiurzm5Ol/KWOGXisUHVx2MXIYqDgPU1/img.png&quot; data-alt=&quot;크롤링 결과 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FFXes/btsiurzm5Ol/KWOGXisUHVx2MXIYqDgPU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFFXes%2Fbtsiurzm5Ol%2FKWOGXisUHVx2MXIYqDgPU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1588&quot; height=&quot;484&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크롤링 결과 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>사이드 프로젝트</category>
      <category>beautifulsoup</category>
      <category>Crawling</category>
      <category>K-Food</category>
      <category>만개의 레시피</category>
      <category>만개의 레시피 크롤링</category>
      <category>사이드 프로젝트</category>
      <category>크롤링</category>
      <category>한식</category>
      <category>한식 가이드</category>
      <category>한식 크롤링</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/393</guid>
      <comments>https://otugi.tistory.com/393#entry393comment</comments>
      <pubDate>Sat, 3 Jun 2023 16:22:45 +0900</pubDate>
    </item>
    <item>
      <title>Forward-Forward Algorithm 논문 리뷰</title>
      <link>https://otugi.tistory.com/392</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘 소개할 논문은 &lt;span style=&quot;color: #000000;&quot;&gt;Geoffrey Hinton의 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;ldquo;The Forward-Forward Algorithm: Some Preliminary Investigations&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rdquo;이다. 2022 NIPS talk에서 다루어졌던 논문으로 22년 12월에 arXiv에 공개된 따끈따끈한 논문이다. 힌튼은 현재 딥러닝 학습의 근간을 이루는 역전파(Backpropagation) 알고리즘의 초기 연구에 참여했던 인물이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Serif KR';&quot;&gt;Backpropagation(이하 BP)은 오늘날 여러 AI 모델들의 learning procedure에 사용되는 중요한 알고리즘이다. 하지만 컴퓨터 과학자이면서 인지심리학자이기도 한 힌튼은 실제 우리 대뇌 피질의 학습 과정이 BP와 유사하지 않다는 점을 지적하면서 새로운 Forward-Forward algorithm(이하 FF)을 제안한다. 간단히 말하자면, BP는 추론(inference)과 학습(learning)의 과정이 나뉘어져있는데 인간은 이 두가지가 동시에 즉각적으로 이루어진다는 점에 착안한 것이다. 최근 FF 알고리즘에 대해 BP를 대체할 수 있는가에 대해 많은 논의들이 이루어지고 있는데, 분명한 것은 Artificial General Intelligence(AGI)로 나아가기 위해서는 이처럼 추론을 하면서 동시에 학습을 해서 자동적, 점진적으로 발전해 나아가는 모델의 등장이 필수적이란 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;What is FF algorithm?&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;FF 알고리즘은 BP와 같이 AI 모델의 learning procedure에 대해 제안된 또 다른 방법이다. 논문에 따르면 FF 알고리즘에는 두 개의 forward pass가 존재한다. positive data(i.e., real data)에 대해 진행되는 positive pass 그리고 negative data(can be generated by perturbing positive data)에 대해 진행되는 negative pass이다. FF 알고리즘에서 각 layer는 고유의 objective를 갖고 있는데 positive data에 대해서는 high goodness를, negative data에 대해서는 low goodness를 갖도록 하는 것이다. Goodness라는 것은 positive data를 얼마나 positive data로 분류하는지를 나타내는 정도이다. BP의 loss function과 유사한 개념인데 뒤에서 더 자세히 설명하겠다. 본 논문에선 layer의 sum of squared activities를 goodness로 사용하였는데 저자는 아직 다른 goodness 정의에 대해 많은 가능성이 있다고 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIH0yJ/btr0GbVTmyN/7pCGunmfWQkTn1Hnzgb30K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIH0yJ/btr0GbVTmyN/7pCGunmfWQkTn1Hnzgb30K/img.png&quot; data-alt=&quot;backpropagation과 forward-forward 알고리즘의 비교(이미지 출처 : https://medium.com/mlearning-ai/pytorch-implementation-of-forward-forward-algorithm-by-geoffrey-hinton-and-analysis-of-performance-7e4f1a26d70f)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIH0yJ/btr0GbVTmyN/7pCGunmfWQkTn1Hnzgb30K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIH0yJ%2Fbtr0GbVTmyN%2F7pCGunmfWQkTn1Hnzgb30K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;710&quot; height=&quot;404&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;backpropagation과 forward-forward 알고리즘의 비교(이미지 출처 : https://medium.com/mlearning-ai/pytorch-implementation-of-forward-forward-algorithm-by-geoffrey-hinton-and-analysis-of-performance-7e4f1a26d70f)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Limitations of BP&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;BP는 neural network의 전파가 최종 layer를 거쳐 최정 output을 낼 때까지 기다렸다가 이를 다시 역전파를 통해 가중치를 갱신한다. 하지만, 저자는 실제 우리의 뇌가 BP 알고리즘처럼 학습한다는 명확한 증거가 없을뿐더러 오히려 뇌영상장치를 통해 학습 시 active한 부분들을 살펴보았을 때 loop를 형성하는 부분들이 관측된다고 말한다.&amp;nbsp; 정확히는 아래와 같이 쓰여있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;The top-down connections from one cortical area to an area that is earlier in the visual pathway do not mirror the bottom-up connections as would be expected if backpropagation was being used in the visual system. Instead, they form loops in which neural activity goes through about half a dozen cortical layers in the two areas before arriving back where it started&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;즉 실제 perceptual system에서 인간은 추론(inference)과 학습(learning)을 동시에 진행하고 여기엔 backpropagation을 위한 time-out이 없다는 것이다. 바꿔말하면, 우리 뇌의 시냅스들은 추론을 하면서 동시에 각각의 unit이 즉각적인 학습을 진행하는 것이지 말단이 output을 낼때까지 기다렸다가 학습이 진행되지 않는다는 것이다. (저자는 FF 알고리즘의 또 다른 특징으로 neural activity를 BP 처럼 store할 필요가 없다는 점을 언급하였는데 이 부분은 사실 읽어도 이해를 잘 못하겠다...) 저자는 논문에서 FF 알고리즘은 특히 low power H/W 환경에서 BP를 능가할 수 있을 것이라고 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;How it works&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;앞서 설명한대로 BP가 forward, backward 두 개의 pass가 존재하는 것과 달리 FF 알고리즘에는 두 개의 pass가 존재한다. 하나는 positive data(real data)에 대해 작동하는 positive pass, 다른 하나는 negative data에 대해 작동하는 negative pass이다. 둘의 동작원리는 동일하지만 positive pass에선 positive data에 대해 goodness를 높이는 방향으로, negative pass에선 negative data에 대해 goodness를 낮추는 방향으로 가중치 updata가 진행된다. 쉽게 말해, threshold 값을 설정해두고 positive data에 대해선 goodness &amp;gt; threshold가 되도록, negative data에 대해선 goodness &amp;lt; threshold가 되도록 학습을 진행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5Vm3S/btr0We32bqI/j4YhKM9SvtQrLCCCkJPUnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5Vm3S/btr0We32bqI/j4YhKM9SvtQrLCCCkJPUnK/img.png&quot; data-alt=&quot;FF의 목표함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5Vm3S/btr0We32bqI/j4YhKM9SvtQrLCCCkJPUnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5Vm3S%2Fbtr0We32bqI%2Fj4YhKM9SvtQrLCCCkJPUnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;529&quot; height=&quot;118&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;118&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FF의 목표함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;식으로는 위와 같이 logistic function &amp;sigma;를 이용해 positive data가 주어졌을 때 positive or negative로 올바르게 분류하는 것이 목적이다. j는 j번째 layer를 y를 그 layer의 hidden unit을 그리고 &amp;theta;는 threshold를 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;787&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPQ7t8/btr0NIdzHHi/3HQPbdwPaT2dDkkZgVx2gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPQ7t8/btr0NIdzHHi/3HQPbdwPaT2dDkkZgVx2gK/img.png&quot; data-alt=&quot;FF 알고리즘의 시각화(이미지 출처 : https://www.youtube.com/watch?v=F7wd4wQyPd8)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPQ7t8/btr0NIdzHHi/3HQPbdwPaT2dDkkZgVx2gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPQ7t8%2Fbtr0NIdzHHi%2F3HQPbdwPaT2dDkkZgVx2gK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1070&quot; height=&quot;787&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;787&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FF 알고리즘의 시각화(이미지 출처 : https://www.youtube.com/watch?v=F7wd4wQyPd8)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 그림에서 BP가 최종 layer를 지나고나서의 loss를 이용하여 최적화하는 것과 달리 FF는 각 layer-level에서의 loss function(goodness)를 최적화한다. 또한 각 layer를 vector로 간주하여 이 vector의 size를 positive data에 대해선 increase하는 방향으로 negative data에 대해선 decrease하는 방향으로 가중치를 갱신한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Experiments with FF&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;저자는 MNIST dataset을 사용해 실험을 진행하였다. 해당 데이터셋은 이미 유명하고 특히 BP를 이용한 여러 모델들에 대한 성능이 잘 나온 것이 입증된 데이터셋이기에 새로운 learning procedure이 제대로 작동하는지 시험하기에 적합하다고 생각되어 선정하였다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Unsupervised Example&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1347&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mJg6U/btr0H8Eoyj6/EtIFFbsJKDmrBo8eKxhZEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mJg6U/btr0H8Eoyj6/EtIFFbsJKDmrBo8eKxhZEk/img.png&quot; data-alt=&quot;negative data generation process for unsupervised example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mJg6U/btr0H8Eoyj6/EtIFFbsJKDmrBo8eKxhZEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmJg6U%2Fbtr0H8Eoyj6%2FEtIFFbsJKDmrBo8eKxhZEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1347&quot; height=&quot;405&quot; data-origin-width=&quot;1347&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;negative data generation process for unsupervised example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;저자는 unsupervised 예시에 대해 MNIST dataset을 이용하여 위와 같이 negative data를 만들었다고 한다. 먼저 positive data인 7과 임의로 생성한 mask를 곱하고 다른 데이터 6을 준비해 이를 reversed된 1-mask와 곱한 뒤 둘을 더해 negative data를 만든다. 이를 이용해 4개의 FC layer를 가진 neural network에서 100에폭동안 학습하여 1.37%의 error rate를 기록했다고 한다. 저자는 실험에서 마지막 3개의 hidden layer의 normalized vector를 sofrmax 함수의 input으로 사용하였다고 하는데, 약간의 트릭같기도 하지만 이는 BP처럼 뒷단에서의 학습 정보가 앞단의 layer에 전달될 수 없으니 모든 layer-level에서의 goodness를 참고해 결과를 얻어내려고 한 듯하다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Supervised Example&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;supervised example의 경우 unsupervised처럼 mask를 만들필요가 없어 더 쉽다. 논문에선 label 정보를 input data에 포함시켜 학습을 진행했다. MNIST data의 first 10 pixels를 label을 나타내는 vector로 사용하였다고 한다. positive data는 이 10개의 픽셀이 correct label로 되어있고, negative data에 대해선 incorrect label로 만들었다고 한다. Inference 시에는 이 10개의 픽셀을 neutral label로 초기화한다. 그리고 각 label(손글씨 데이터셋이니 이 경우 0~9)에 대해 추론을 한 뒤 가장 높은 goodness를 보인 숫자로 최종 output을 결정한다. 이처럼 모든 label에 대해 label의 갯수만큼 inference하는 작업이 필요하다는 것이 FF 알고리즘의 단점인 듯하다. 논문에선 4개의 FC layer에서 60 에폭동안 학습하여 1.36%의 error rate를 기록했다고 한다. 참고로 BP는 20에폭만에 같은 성능을 도달하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;870&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kXbmU/btr0IFBV94J/eFutnb83jfM8xyRsDhEk80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kXbmU/btr0IFBV94J/eFutnb83jfM8xyRsDhEk80/img.png&quot; data-alt=&quot;unsupervised example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kXbmU/btr0IFBV94J/eFutnb83jfM8xyRsDhEk80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkXbmU%2Fbtr0IFBV94J%2FeFutnb83jfM8xyRsDhEk80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1151&quot; height=&quot;870&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;870&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;unsupervised example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Result on CIFAR-10 dataset&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;954&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Spqxp/btr0HthIG3d/zKSHukHAlbFIsVaUE2OehK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Spqxp/btr0HthIG3d/zKSHukHAlbFIsVaUE2OehK/img.png&quot; data-alt=&quot;result on the CIFAT-10 dataset&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Spqxp/btr0HthIG3d/zKSHukHAlbFIsVaUE2OehK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSpqxp%2Fbtr0HthIG3d%2FzKSHukHAlbFIsVaUE2OehK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;877&quot; height=&quot;954&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;954&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;result on the CIFAT-10 dataset&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;저자는 CIFAR-10 데이터셋에 대해서도 실험을 하였는데, MNIST와 마찬가지로 이미지 분류 데이터셋이다. 위 표에서 BP는 backpropagation, FF는 forward-forward 알고리즘이다. compute goodness for every label이 supervised 방식, one-pass softmax가 unsupervised 방식이다. ssq는 sum of squared activity라는 goodness metric인데 min ssq는 이를 최소화하는 것이고, max ssq는 이를 최대화하는 방향으로 학습을 진행한 것이다. 표를 보면 training error는 BP에 비하면 FF 알고리즘이 아주 높지만, 주목할만한 부분은 test error에 대해서는 BP에 비해 크게 성능이 차이나지 않는다는 점이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;FF 알고리즘이 과연 BP를 대체할 수 있을지는 아직 확실히 모르겠다. 하지만 error rate를 보았을 때 학습이 진행되고 있다는 것이 새로운 학습 알고리즘으로서의 가능성을 보여준다고 생각된다. 저자도 언급했듯이 더 나은 goodness function에 대한 정의, large model에서의 성능과 같이 연구되어야 할 것이 많이 남아있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Deep Learning Paper Review</category>
      <category>2022NIPS</category>
      <category>backpropagation</category>
      <category>forward forward algorithm</category>
      <category>forward forward 알고리즘</category>
      <category>hinton</category>
      <category>머신 러닝</category>
      <category>모델 학습 알고리즘</category>
      <category>역전파 알고리즘</category>
      <category>제프리 힌튼</category>
      <category>학습 알고리즘</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/392</guid>
      <comments>https://otugi.tistory.com/392#entry392comment</comments>
      <pubDate>Sun, 26 Feb 2023 15:20:07 +0900</pubDate>
    </item>
    <item>
      <title>OpenAI ChatGPT에 대한 소개와 능력 및 한계</title>
      <link>https://otugi.tistory.com/391</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;OpenAI의 ChatGPT가 공개되었다. &lt;s&gt;사실 공개된지 좀 되었지만.... 논문쓰고 제출하느라 이제야 사용해본 나...&lt;/s&gt;&amp;nbsp; 이미 미디어에 많이 노출이 되어서 다들 알겠지만 간단히 설명하자면 ChatGPT는 챗봇 형식의 AI이다. 구글, 네이버, 다음에 검색하듯이 키워드나 명사형으로 검색을 하는 것이 아니라 그냥 사람과 대화하듯이 질문하면 답을 찾아주는 것이다. 음... 좀 더 쉽게 비유하자면 미래를 그린 SF 영화에 나오는 AI 비서 같은 거라고 생각하면 된다. &quot;이거이거 찾아줘~&quot;, &quot;이거이거 알려줘~&quot;와 같은 질문에 대답해주는 AI이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;관련된 분야를 연구하고 있어서 한 번 사용해보았는데 성능이 꽤 괜찮은 것 같았다. 내가 놀랐던 점은 말을 꽤나 잘한다는 것이다. 지금까지의 챗봇들은 response를 잘 생성하긴 했지만 생성한 말이 syntactic한 측면에서 오류가 있거나 어색한 경우가 있었는데, ChatGPT는 해당 response가 팩트인지와는 별개로 정말 자연스럽게 말을 생성한다는 점이었다. 이 포스팅에서는 지금 한창 많은 관심을 받고 있는 ChatGPT에 대해서 실제로 사용해본 결과를 바탕으로 자세히 설명해보고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;ChatGPT FAQ&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHczFZ/btrYyU1LLiH/DQu7hKOHSAEklqBZZPeHBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHczFZ/btrYyU1LLiH/DQu7hKOHSAEklqBZZPeHBk/img.png&quot; data-alt=&quot;OpenAI 홈페이지에 올라온 ChatGPT 관련 FAQ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHczFZ/btrYyU1LLiH/DQu7hKOHSAEklqBZZPeHBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHczFZ%2FbtrYyU1LLiH%2FDQu7hKOHSAEklqBZZPeHBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1234&quot; height=&quot;693&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OpenAI 홈페이지에 올라온 ChatGPT 관련 FAQ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 사진은 OpenAI 홈페이지에 올라온 ChatGPT와 관련된 FAQ의 일부를 발췌한 것이다. ChatGPT는 현재 &lt;a href=&quot;https://openai.com/blog/chatgpt/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OpenAI 홈페이지&lt;/a&gt;에서 무료로 사용이 가능하다. FAQ 1번을 보면 initial research preview 기간 동안 무료로 사용이 가능하다고 한다. 알파고 급의 AI 쇼크에 현재 이용자수가 폭증하고 있다고 하는데 조만간 유료로 전환될 것 같다(이미 전환 얘기가 나오기도 했지만). ChatGPT 모델 크기도 매우 큰데 이를 이용해 inference를 돌려 response를 생성하는데에도 어마어마한 computing cost가 들 것이다. 이를 기업이 그냥 모두에게 언제까지고 개방해둘리가 없다...&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;6번 문항을 보면 user들의 대화 기록이 AI trainer들에 의해 review 될거라고 한다. 11번 문항에선 OpenAI라는 기업이 preview 기간 동안 strength와 weakness를 파악하기 위해 현재 이용 가능하도록 만들어두었다고 한다. 이를 통해서 추측해보건데, 아마 OpenAI가 엄청난 성능의 ChatGPT를 무료로 풀어둔 이유는 폭발적인 user들로부터 생성된 방대한 conversation data를 이용해 further training에 사용하고, feedback을 반영해 다음 release 때에 반영하기 위한게 아닌가 싶다. 실제로 사용해보면 각각의 답변에 대해 feedback을 할 수 있는 버튼이 우측에 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;현재 API로는 사용할 수 없다고 하는데 이는 추후 나온다고 하니 기다려보면 될 듯하다. &lt;a href=&quot;https://share.hsforms.com/1u4goaXwDRKC9-x9IvKno0A4sk30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;API 사용 신청 form&lt;/a&gt;을 작성하고 waitlist에 이름을 넣어두면 된다. 개발자 커뮤니티의 무수한 요청에 의해 곧 API를 만들 예정이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqxVNj/btrYsPmLqWH/lIXLjoiANUfytNDHk9oXgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqxVNj/btrYsPmLqWH/lIXLjoiANUfytNDHk9oXgk/img.png&quot; data-alt=&quot;ChatGPT API Waitlist&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqxVNj/btrYsPmLqWH/lIXLjoiANUfytNDHk9oXgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqxVNj%2FbtrYsPmLqWH%2FlIXLjoiANUfytNDHk9oXgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1466&quot; height=&quot;436&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChatGPT API Waitlist&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;ChatGPT introduction on site UI&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래는 홈페이지에 공개된 ChatGPT와 관련된 소개이다. &lt;b&gt;&quot;occasionally generate incorrect or misleading information&quot;&lt;/b&gt;이라고 되어있는데, 때때로 틀린(사실과 다른) 혹은 오해의 소지가 있는 정보를 제공하기도 한다고 소개하고 있다. 이는 뒤에서 한계점을 설명할 때 더 자세히 언급하겠다.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uJJiv/btrYzLJ0u4J/lJ2wTHyFM01Cajs1ymEnr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uJJiv/btrYzLJ0u4J/lJ2wTHyFM01Cajs1ymEnr1/img.png&quot; data-alt=&quot;OpenAI 홈페이지에 공개된 ChatGPT 소개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uJJiv/btrYzLJ0u4J/lJ2wTHyFM01Cajs1ymEnr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuJJiv%2FbtrYzLJ0u4J%2FlJ2wTHyFM01Cajs1ymEnr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;933&quot; height=&quot;419&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OpenAI 홈페이지에 공개된 ChatGPT 소개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by3K89/btrYz9DQ5aJ/OAocGcNxLiaDr5jQEUQ6p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by3K89/btrYz9DQ5aJ/OAocGcNxLiaDr5jQEUQ6p1/img.png&quot; data-alt=&quot;User data를 수집하는 OpenAI&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by3K89/btrYz9DQ5aJ/OAocGcNxLiaDr5jQEUQ6p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby3K89%2FbtrYz9DQ5aJ%2FOAocGcNxLiaDr5jQEUQ6p1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;933&quot; height=&quot;422&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;User data를 수집하는 OpenAI&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;OpenAI는 user data를 수집한다고 한다. 이를 아마 차후의 release 때에 성능 개선을 위한 추가 데이터로 사용할 생각인 것 같다. 위 사진에 보면 &quot;Please don't share any sensitive information in your conversations.&quot;라고 되어있는데 아마도 data collection 과정에서 user의 input text에 대한 privacy filtering이 되지는 않는 것 같다...(혹은 filtering 과정을 거치더라도 완벽함을 보장할 수 없거나)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Examples &amp;amp; Capabilities&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;618&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/22YrZ/btrYyelTLGl/AGvPDjytg3fpZz9QklYf8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/22YrZ/btrYyelTLGl/AGvPDjytg3fpZz9QklYf8k/img.png&quot; data-alt=&quot;홈페이지에 소개된 ChatGPT의 사용 예시, 능력, 한계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/22YrZ/btrYyelTLGl/AGvPDjytg3fpZz9QklYf8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F22YrZ%2FbtrYyelTLGl%2FAGvPDjytg3fpZz9QklYf8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;618&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;618&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;홈페이지에 소개된 ChatGPT의 사용 예시, 능력, 한계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Examples&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;위 사진은 홈페이지에 소개된 ChatGPT의 사용 예시, 능력, 한계점이다. Examples를 보면 다음과 같은 것들이 가능하다는 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Information&lt;/b&gt; : &quot;Explain quantum computing in simple terms&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Brainstorming&lt;/b&gt; : &quot;Got any creative ideas for a 10 year old's birthday?&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Nocode AI&lt;/b&gt; : &quot;How do I make an HTTP request in Javascript?&quot;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;먼저 사용자에게 정보를 제공해주는 information 기능은 기존의 챗봇과 큰 차별점은 아니다. coverage가 큰 방대한 데이터로 학습을 했다면 사용자가 요구하는 것에 대한 정보를 제공해줄 수 있으니까. &quot;Javascript로 HTTP request를 보내는 코드르 짜줘.&quot;와 같은 nocode AI도 요즘 이와 관련된 기능을 탑재한 AI 모델들이 많이 출시되고 있어서 크게 놀랍지는 않다. 개인적으로는 idea를 제시해주는 brainstorming 기능이 흥미로웠다. 마치 사람이 생각하는 것과 같이 특정 상황이나 문제해결에 대해 여러 아이디어를 제시해준다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Capabilities&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;소개된 능력들을 보면 대략 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Dialogue history&lt;/b&gt; : &quot;Remember what user said earlier in the conversation.&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Follow-up correction&lt;/b&gt; : &quot;Allow user to provide follow-up corrections&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Safety&lt;/b&gt; : &quot;Trained to decline inappropriate requests&quot;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;첫째로, 이전의 대화 기록을 메모리에 기억해두고 대화를 생성한다는 점이다. conversational AI 모델의 문제로 많이 거론되었던 것이 바로 이전 대화 기록을 가지고 가는 장기기억 문제이다. 사람의 경우 이전에 대화한 내용을 기억하고 다음 대화를 이어나갈 수 있지만 이를 AI 모델에 적용하기는 쉽지 않은 문제이다. ChatGPT와 같이 모델의 크기가 커지면 input size도 자연스레 커지게 되니 이전 대화의 내용을 기억하도록 함께 input으로 주어 답변을 생성하도록 만들 수 있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;둘째로, &lt;b&gt;추가 질의를 통한 답변 개선&lt;/b&gt;이 가능하다는 점이다. 이 부분이 흥미로웠는데 아마 기존 챗봇들과의 가장 큰 차별점이 아닌가 싶다. 기존 챗봇들의 경우 단순히 해당 질문에 대한 답변만을 생성하고 만약 해당 답변이 틀렸다면 사용자가 다른 방식으로 질문을 다시 던져야만 했다. 하지만 ChatGPT는 추가적인 질의를 통해 (마치 사람과 대화하듯이) 답변을 점진적으로 개선해 나아가는 것이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;셋째로, safety 기능인데 부적절한 질문에 대해서는 decline할 수 있도록 학습되었다는 것이다. 얼마전부터 대화형 AI의 윤리의식과 관련된 문제들이 많이 제기되어 왔다. AI가 사용자로부터 부적절한 단어들을 학습하거나 위험한 질문에 대해 답해주는 경우 등이 있다. ChatGPT는 이러한 문제를 해결하기 위해 safety를 고려한 training을 통해 부적절한 질문에 대한 답변을 생성하지 못하도록 했다고 한다. 아마 내부적으로 user input에 대한 safety scoring을 통해 점수를 메기거나 혹은 부적절하다고 판단될 수 있는 질문들에 대해 binary classfication으로 학습을 해둔 것이 아닐까 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Brainstorming&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Serif KR';&quot;&gt;아래 사진은 ChatGPT에게 내가 현재 연구하고 있는 분야인 conversational AI에 대한 창의적인 아이디어를 몇 가지 제시해달라고 요청한 결과이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PUZ8c/btrYwmLfMrG/4oGkcKfdJJbu3in28K1d31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PUZ8c/btrYwmLfMrG/4oGkcKfdJJbu3in28K1d31/img.png&quot; data-alt=&quot;대화형 AI에 대한 연구 주제를 제시해주는 ChatGPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PUZ8c/btrYwmLfMrG/4oGkcKfdJJbu3in28K1d31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPUZ8c%2FbtrYwmLfMrG%2F4oGkcKfdJJbu3in28K1d31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1182&quot; height=&quot;685&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;685&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;대화형 AI에 대한 연구 주제를 제시해주는 ChatGPT&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;꽤나 reliable하고 trend를 반영하는 답변을 내놓는 것을 알 수 있다. 사실 매우 놀랐다. &lt;span style=&quot;color: #000000;&quot;&gt;특히 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sarcasm&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이나 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;humor&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 이해하는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI, multi-lingual dialog model, knowledge graph &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기반의 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dialog model, ethical issue와 같은 것들은&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; conversational AI 분야의 최근 나온 conference &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;paper&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;나 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;survey paper&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;들에서도 많이 언급되는 것들이다. 그런데 문득, 이러한 것들이 AI가 (마치 생각을 하는 사람처럼) 내부적인 로직을 통해 내놓는 brainstorming이 아니라 방대한 데이터에서 학습한 정보들을 정보를 알려주는 information 기능과 같이 답변으로 생성하는 것일 수도 있겠다는 생각이 들었다. 즉, 위 예시 같은 경우는 AI가 여러 아이디어를 제시해주는 것 같아 보이지만 실제로는 여러 학술 정보들을 학습한 결과를 단순히 요약해서 보여주는 것일 수도 있는 것이다. 이를 확인하기 위해 &lt;b&gt;'정보가 매우 적거나 혹은 없을법한 주관적인 질문'&lt;/b&gt;을 해보았다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Serif KR';&quot;&gt;아래와 같이 &quot;&lt;u&gt;인간관계에 스트레스를 많이 받을 수 있는 방법&lt;/u&gt;&quot; 그리고 &quot;&lt;u&gt;공부를 못하는 방법&lt;/u&gt;&quot;을 물어보았다. 대부분의 정보들은 아마 인간관계에서 스트레스를 덜 받는 방법 그리고 공부를 잘하는 방법에 초점이 맞추어 구성되었을 거라고 생각했다. 생성한 답변을 보면 꽤나 말이 된다는 것을 알 수 있다. (답변이 재미있으니 한 번 읽어보길 바란다) 아마 &lt;b&gt;단순한 정보의 학습 외에도 reasoning&lt;/b&gt;을 할 수 있는 능력도 함께 학습된 게 아닌가 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnmrla/btrYAl5pqal/YTelEUKIG6Wu9uPO6hbA81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnmrla/btrYAl5pqal/YTelEUKIG6Wu9uPO6hbA81/img.png&quot; data-alt=&quot;인간관계에서 스트레스를 많이 받는 방법을 알려주는 ChatGPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnmrla/btrYAl5pqal/YTelEUKIG6Wu9uPO6hbA81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdnmrla%2FbtrYAl5pqal%2FYTelEUKIG6Wu9uPO6hbA81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;853&quot; height=&quot;480&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인간관계에서 스트레스를 많이 받는 방법을 알려주는 ChatGPT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtinzN/btrYtxmbKuV/SEf85iEGcbogNsMLsym8vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtinzN/btrYtxmbKuV/SEf85iEGcbogNsMLsym8vk/img.png&quot; data-alt=&quot;공부를 못하는 방법을 알려주는 ChatGPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtinzN/btrYtxmbKuV/SEf85iEGcbogNsMLsym8vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtinzN%2FbtrYtxmbKuV%2FSEf85iEGcbogNsMLsym8vk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;436&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공부를 못하는 방법을 알려주는 ChatGPT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Probability-based Generation model&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ChatGPT는 기본적으로 text generation model이다. 많은 text generation language model들은 확률 기반의 토큰 생성 방식으로 text를 generation 한다. 그래서인지 ChatGPT 역시도 같은 input에 대해서도 매 running마다 조금은 다른 답변을 내놓았다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nbR6W/btrYzpOavWB/GSH9gv26iwGKcDu9sbQL30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nbR6W/btrYzpOavWB/GSH9gv26iwGKcDu9sbQL30/img.png&quot; data-alt=&quot;같은 답변에 대해 매 running마다 조금씩 다른 답변을 내놓는 ChatGPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nbR6W/btrYzpOavWB/GSH9gv26iwGKcDu9sbQL30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnbR6W%2FbtrYzpOavWB%2FGSH9gv26iwGKcDu9sbQL30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1345&quot; height=&quot;822&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;같은 답변에 대해 매 running마다 조금씩 다른 답변을 내놓는 ChatGPT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Dialogue history&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ChatGPT의 capability에서 언급된 대화 기록 저장 기능을 시험해보기 위해 아래와 같은 질의를 던져보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1943&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v75Pi/btrYsaSqtmc/eoJFkjROpVYhsnJEKSLOCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v75Pi/btrYsaSqtmc/eoJFkjROpVYhsnJEKSLOCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v75Pi/btrYsaSqtmc/eoJFkjROpVYhsnJEKSLOCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv75Pi%2FbtrYsaSqtmc%2FeoJFkjROpVYhsnJEKSLOCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1943&quot; height=&quot;856&quot; data-origin-width=&quot;1943&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;일부러 여러 의미를 가진 단어를 선택해 물어보았다. GIST는 위장관 기질종양, geographically-weighted inverse squared time, 어떤 말이나 글의 핵심 그리고 마지막으로 내가 다니고 있는 광주과학기술원 등과 같이 여러 의미를 갖고 있다. 아마 ChatGPT가 처음에는 이러한 것을 구분하지 못할거라고 생각해서 해당 단어에 대해 물어보았다. 그리고 다음 질문으로 내가 의도하는 광주과학기술원에 대해 설명해달라고 하였고, 그 다음으로 GIST에 대해 다시 물어보았다. 결과적으로 ChatGPT는 &lt;b&gt;이전 대화 기록을 기억해 사용자가 의도하는&lt;/b&gt; GIST가 광주과학기술원임을 인지하고 이에 대해 설명해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Follow-up correction&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다음으로는 ChatGPT의 &lt;b&gt;follow-up correction&lt;/b&gt; 기능을 테스트해보기 위해 &lt;b&gt;야간 소음에 대한 경고문&lt;/b&gt;을 작성해달라고 요청하였다. 그 후, 해당 경고문을 좀 더 짧게 작성해달라고 하였고 마지막으로 좀 더 강한 어조로 작성해달라고 순차적으로 요청하였다. 아래는 그 결과이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0al2d/btrYsO2E41K/RllgMeKApmy4eWRlASZujK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0al2d/btrYsO2E41K/RllgMeKApmy4eWRlASZujK/img.png&quot; data-alt=&quot;ChatGPT에게 야간 소음에 대한 경고문 작성 요청&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0al2d/btrYsO2E41K/RllgMeKApmy4eWRlASZujK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0al2d%2FbtrYsO2E41K%2FRllgMeKApmy4eWRlASZujK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;947&quot; height=&quot;606&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChatGPT에게 야간 소음에 대한 경고문 작성 요청&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWhK82/btrYyUA2SPi/6Vd1UkRrDboKtbt6IzMyc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWhK82/btrYyUA2SPi/6Vd1UkRrDboKtbt6IzMyc0/img.png&quot; data-alt=&quot;좀 더 짧은 경고문 작성을 요청&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWhK82/btrYyUA2SPi/6Vd1UkRrDboKtbt6IzMyc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWhK82%2FbtrYyUA2SPi%2F6Vd1UkRrDboKtbt6IzMyc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;947&quot; height=&quot;297&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;좀 더 짧은 경고문 작성을 요청&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nLOeS/btrYzaqfDi6/iucs0XLKHn58vjbG8jV6I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nLOeS/btrYzaqfDi6/iucs0XLKHn58vjbG8jV6I0/img.png&quot; data-alt=&quot;좀 더 강한 어조로 경고문 작성을 요청&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nLOeS/btrYzaqfDi6/iucs0XLKHn58vjbG8jV6I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnLOeS%2FbtrYzaqfDi6%2Fiucs0XLKHn58vjbG8jV6I0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;948&quot; height=&quot;590&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;좀 더 강한 어조로 경고문 작성을 요청&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;두 번째 경고문은 첫 번째 작성한 경고문보다 짧아졌다. 이는 단순히 summarization 기능을 사용해서도 구현할 수 있다고 생각이 되어서 &lt;u&gt;좀 더 강한 어조로&lt;/u&gt; 작성해 달라는 마지막 질문을 추가적으로 던져보았다. 첫 번째 경고문과 비교해보면 &quot;unacceptable&quot;, &quot;thoughtless actions&quot;, &quot;immediate action&quot;과 같은 강한 어조의 단어들이 사용된 것을 알 수 있다. 이 같은 추가질의를 통한 답변개선 기능이 ChatGPT 모델의 차별성이기도 하지만 더더욱 사람과의 대화같이 느껴졌다. 우리들도 대화를 하는 상대방의 의도를 처음부터 파악하기도 하지만 이런저런 추가적인 대화를 이어나가면서 알아가기도 하고 더 나은 답변을 하기도 하니까 말이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Nocode AI&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Examples에 마지막으로 소개된 기능은 nocode AI 기능이다. ChatGPT에게 주어진 숫자가 소수인지를 판별하는 함수를 파이썬으로 짜달라고 해보았다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4yKGd/btrYsaStstF/OG0qdeRXQIEnVdAhE76Gyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4yKGd/btrYsaStstF/OG0qdeRXQIEnVdAhE76Gyk/img.png&quot; data-alt=&quot;ChatGPT가 작성해준 소수판별 파이썬 함수 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4yKGd/btrYsaStstF/OG0qdeRXQIEnVdAhE76Gyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4yKGd%2FbtrYsaStstF%2FOG0qdeRXQIEnVdAhE76Gyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;915&quot; height=&quot;657&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChatGPT가 작성해준 소수판별 파이썬 함수 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;공식 문서에는 해당 코드, 코드에 대한 설명 그리고 에러에 대한 설명을 함께 input으로 제공하면 debugging 기능도 수행할 수 있다고 한다. 그래서 위 코드에서 빨간 밑줄 부분을 바꾸어서 일부러 잘못된 코드(자연수 1은 소수가 아님에도 아래 코드는 1에 대해 True를 return하므로)를 만든 뒤 수정해달라고 요청해보았다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSANIt/btrYzLwIpGh/iwMcKMafFr774uLJZilWA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSANIt/btrYzLwIpGh/iwMcKMafFr774uLJZilWA1/img.png&quot; data-alt=&quot;debugging을 수행하는 ChatGPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSANIt/btrYzLwIpGh/iwMcKMafFr774uLJZilWA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSANIt%2FbtrYzLwIpGh%2FiwMcKMafFr774uLJZilWA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;953&quot; height=&quot;930&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;debugging을 수행하는 ChatGPT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ChatGPT는 해당 코드의 잘못된 부분을 정확히 지적하여 수정하였고, 심지어 추가질의를 통해 시간복잡도가 더 개선된 코드를 알려주었다....ㄷㄷ(&lt;s&gt;?? : 인간시대의 끝이 도래했다...&lt;/s&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Limitations&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 이런 완벽해 보이는 ChatGPT에도 아직 한계점이 존재한다. 바로 &lt;b&gt;사실관계와 무관하게 잘못된 정보를 마치 그럴듯한 문장으로 지어내 제공한다는 점&lt;/b&gt;이다. 학계에서는 본 적도, 들은 적도 없는 정보를 마치 사실인 양 제공한다고 하여 이를 챗봇의 &lt;b&gt;Hallucination(환상, 환청)&lt;/b&gt; 문제라고 부른다. ChatGPT도 바로 이같은 Hallucination 문제를 갖고 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;BART는 NLP 분야에서 많이 사용되는 대표적인 Language model이다. 이를 오인하도록 아래와 같이 &lt;b&gt;&quot;BART가 왜 NLP가 아닌 Vision 분야에서 성공을 거두었는지&quot;&lt;/b&gt;에 대해 물어보았다. 그러자 ChatGPT는 마치 BART 모델이 NLP가 아닌 Vision 분야에서 큰 성공을 거둔 것이 사실인 것처럼 해당 이유에 대해 설명하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;설명한 성공의 이유들을 읽어보면 꽤나 그럴듯하다. BART가 language model이라는 사전지식이 없는 사람이 검색을 했다면 충분히 오해를 불러 일으킬 수 있는 것이다. 바로 이러한 점들이 Conversational AI의 Hallucination이 문제시 되는 이유이다. 잘못된 정보를 마치 사실인양 제공하니까 말이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj9yzo/btrYydnhavB/UTHRamYKtzkgELnAK6Etx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj9yzo/btrYydnhavB/UTHRamYKtzkgELnAK6Etx0/img.png&quot; data-alt=&quot;ChatGPT hallucination example 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj9yzo/btrYydnhavB/UTHRamYKtzkgELnAK6Etx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj9yzo%2FbtrYydnhavB%2FUTHRamYKtzkgELnAK6Etx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1103&quot; height=&quot;775&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChatGPT hallucination example 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;추가적으로 이제는 모든딥러닝 분야에서 사용 중인 back-propagation 논문을 내가 언제 작성했는지 물어보았다. 그랬더니 아래와 같이 답변해주었다. 하지만...나는 물론이고, Sung-Bae Cho와 Se-Young Yun은(누군진 모르겠지만) back-propagation paper를 작성한 사람들이 아니다...몇 가지 질문을 던져본 결과, ChatGPT는 &lt;b&gt;false prompt&lt;/b&gt;에 약한 듯하다. 사용자가 input으로 주는 질문에 대해 어느 정도 True라고 사실관계를 생각하고 답변을 생성하는 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJJznE/btrYBcgbUSO/KUBtjoUNSGgPkIpI2zZwg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJJznE/btrYBcgbUSO/KUBtjoUNSGgPkIpI2zZwg1/img.png&quot; data-alt=&quot;ChatGPT hallucination example 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJJznE/btrYBcgbUSO/KUBtjoUNSGgPkIpI2zZwg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJJznE%2FbtrYBcgbUSO%2FKUBtjoUNSGgPkIpI2zZwg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;895&quot; height=&quot;191&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChatGPT hallucination example 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;글을 마치며...&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ChatGPT가 정말 많은 화제를 낳고 있는 것 같다. 미디어에서도 온통 ChatGPT에 대한 소개들이 주를 이루고 있다. 실제로 사용해본 결과 정말 놀라운 성능을 보여주고 무엇보다도 &lt;u&gt;정말 자연스러운 글&lt;/u&gt;을 작성한다는 점이 신기했다. 하지만 마지막에 언급한 &lt;b&gt;Hallucination은 어찌보면 매우 큰 문제&lt;/b&gt;일 수도 있다. &lt;u&gt;오해를 불러일으키지 않기 위해선 잘못된 정보나 AI가 학습하지 않아 모르는 정보의 경우 사용자에게 제공하지 않는 것이 최선일 것이다.&lt;/u&gt; 어쩌면 앞으로는 챗봇, AI비서 등이 제공하는 정보의 신뢰성과 관련한 &lt;b&gt;fact-checking&lt;/b&gt;이나 &lt;b&gt;reponse의 reliability를 scoring&lt;/b&gt;하거나 &lt;b&gt;AI가 스스로 incorrectness를 판별하도록 하는 학습&lt;/b&gt;과 같은 분야에서의 연구가 많이 등장할 것 같다. 나도 연구를 하고 있는 입장이지만 AI의 발전 속도가 점점 무서워지기 시작했다 ㅋㅋㅋ&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>NLP</category>
      <category>ai챗봇</category>
      <category>Chatbot</category>
      <category>ChatGPT</category>
      <category>conversational AI</category>
      <category>nlp</category>
      <category>OpenAI</category>
      <category>대화형 AI</category>
      <category>언어모델</category>
      <category>챗봇</category>
      <category>챗지피티</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/391</guid>
      <comments>https://otugi.tistory.com/391#entry391comment</comments>
      <pubDate>Wed, 8 Feb 2023 16:54:41 +0900</pubDate>
    </item>
    <item>
      <title>[Git] Merge Conflict 발생 시 해결 방법, Git pull 오류 시 강제로 실행</title>
      <link>https://otugi.tistory.com/390</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;서로 다른 두 개의 브랜치에서 작업하다가 브랜치를 합칠 때 충돌이 생기는 것을 &lt;u&gt;merge conflict(병합충돌)&lt;/u&gt;라고 한다. 보통 둘 이상의 사람이 협업을 할 때 발생하곤 하는데 서로 다른 브랜치에다 작업을 하다가 최종적으로 프로젝트의 큰 흐름을 담고 있는 master 브랜치로 합칠 때 이런 문제가 자주 발생한다. Git은 기본적으로 &lt;u&gt;Version Control Service(VCS)&lt;/u&gt;이다. 때문에 merge conflict가 발생하면 &lt;u&gt;pull&lt;/u&gt;을 할 수가 없다.(만약 이러한 상황을 무시하고 그냥 pull을 가능하게 만들어버리면 사용자의 로컬에 있는 파일들이 모두 리모트 저장소의 코드로 덮어씌워져 버리기 때문이다.) 물론, 이와 동일한 이유로 pull뿐만 아니라 &lt;u&gt;commit&lt;/u&gt;도 되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이러한 merge conflict는 서로 &lt;u&gt;동일한 이름의 파일&lt;/u&gt;의 &lt;u&gt;동일한 부분&lt;/u&gt;을 서로 다르게 수정했기 때문에 발생한다. 이런 경우 Git에게 사용자가 어떠한 부분을 선택해 최종 수정본에 반영할 것인지를 알려주어야 conflict를 해결할 수 있다. 왜냐하면 Git은 어떤 것으로 최종 수정 사항에 반영해야 하는지를 모르기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이러한 경우에 &lt;u&gt;자신의 로컬에 있는 코드들을 리모트 저장소에 있는 코드들로 강제로 덮어씌워서 해결하는 방법&lt;/u&gt;도 있다. 가령, 자신이 코드에서 어떤 부분을 잘못 수정해서 그냥 처음으로 되돌려 다시 작업을 하고 싶다거나 혹은 자신이 작업하지 않는 다른 브랜치(그러니까 merge하려는 브랜치)의 내용을 우선적으로 반영하고 싶은 경우가 그러하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이런 경우 아래와 같은 커맨드를 사용해 강제로 git pull을 실행해 conflict를 해결할 수 있다. 아래 방법은 Repository에서 최신 commit 정보를 가져와 강제로 HEAD를 옮긴 후 저장하는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. git pull을 하기 위해 깃허브의 레포지토리에서 모든 커밋 정보를 확인한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671367623408&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git fetch --all&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. git reset을 통해 HEAD가 최신 커밋 정보를 가리키도록 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671367700803&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git reset --hard origin/master&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;reset은 HEAD의 위치를 옮기는 명령어이고, --hard 옵션은 강제로 깃명령어를 실행하는 옵션이다. 뒤의 origin/master는 해당 브랜치의 이름에 맞게 수정해주면 된다. 만약 자신의 레포지토리의 경우 마스터 브랜치의 이름이 master라면 git reset --hard master라고 입력하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;3. 이제 git pull을 통해 가져온 정보를 저장한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671367773137&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git pull&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git</category>
      <category>git commit 안될 때</category>
      <category>git pull 안될 때</category>
      <category>github</category>
      <category>merge conflict 해결</category>
      <category>깃</category>
      <category>깃허브</category>
      <category>깃헙</category>
      <category>병합충돌</category>
      <category>커밋 안됨</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/390</guid>
      <comments>https://otugi.tistory.com/390#entry390comment</comments>
      <pubDate>Sun, 18 Dec 2022 21:52:53 +0900</pubDate>
    </item>
    <item>
      <title>[감상평] 자신있게 결정하라 - 칩 히스, 댄 히스</title>
      <link>https://otugi.tistory.com/388</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 최근 개인적인 진로 문제로 이런저런 고민을 하던 날들이 반복되었다. 이랬던 적이 없던 것은 아니다. 일을 하기 시작하면 진로 고민은 없어질 것이라는 나의 예상은 일을 하면서 오히려 더 심해진 앞날에 대한 고민으로 보기 좋게 빗나가버렸다.^^ 고민에 빠진 사람의 생활패턴은 마치 정해진 수순이 있는 것 같다. 계속된 고민은 불안을 데려오고, 선택에 대한 압박감은 초조함을 데리고 왔다. 잠 들지 못하는 밤이 더 잦아졌고, 계속된 수면부족과 스트레스로 오히려 깨어있는 시간에 우울한 감정은 배가 되었다. 제대로 선택을 하지 못하는 날들이 많아지자, 나는 점차 일상생활에서의 작은 것들도 스스로 결정하지 못하게 되었다. 가령, 무엇을 먹을지와 같은 것도 말이다. 지금와서 돌이켜보면, 선택을 하지 못하는 순간이 지속되는 것은 자기효능감을 많이 떨어지게 만드는 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 어찌보면 그때의 나는 내 주변의 친구들보다는 조금 더 일찍 사회생활을 시작하며 &quot;앞날을 걱정하는&quot; 백신을 조금 더 빨리 맞았던 것 같다. 그래서인지 이번에는 그때만큼 고민의 시기가 길어지지 않았고, 그때만큼 힘든 나날을 보내지는 않았다. 내가 진로에 대한 깊은 동굴 속에서 나와 깨닫게 된 것은 결국 이는 &lt;b&gt;&quot;결정의 문제&quot;&lt;/b&gt;라는 점이다. 그렇다면 선택을 조금 더 잘 할 수 있는 방법은 없을까라는 생각을 하게 되어 이 책을 읽게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xhgRr/btrPQMrKhGD/tRt3T43qoBTgeZiQkCvKk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xhgRr/btrPQMrKhGD/tRt3T43qoBTgeZiQkCvKk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xhgRr/btrPQMrKhGD/tRt3T43qoBTgeZiQkCvKk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxhgRr%2FbtrPQMrKhGD%2FtRt3T43qoBTgeZiQkCvKk1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;400&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 책에서 말하는 것은 간단하다. &lt;b&gt;&quot;결정을 잘 하는 방법&quot;&lt;/b&gt;이다. 저자는 말한다. 우리가 선택이라는 것에 대해 많은 고민을 하는 이유는 선택을 하는 행위는 순간이지만 그에 대한 영향을 앞으로 계속 받게되기 때문이라고 한다. 역행자의 저자인 자청 역시도 인생은 &lt;b&gt;&quot;의사결정의 총합&quot;&lt;/b&gt;이라고 하였다. 그만큼 우리는 인생이라는 시간 속에서 크고 작은 여러 결정들을 반복하며 지금의 우리를 만들어낸다. 하지만, 인간은 순간의 감정에 의해서 결정을 내려버리는 경우도 많고, 때로는 모종의 데드라인에 맞추어 촉박한 상태에서 그냥 결정해버리는 경우도 많다. &lt;b&gt;그렇다면 이러한 &quot;결정의 프로세스&quot;를 좀 더 잘 하도록 하는 방법은 무엇일까?&lt;/b&gt;에 대해 저자는 소개한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 책을 읽으며 저자가 소개한 의사결정 프로세스에 따라 나의 경우에 적용시켜가며 종이에 내 생각을 써내려갔다. 그러자 모호했던 생각들이 조금은 정리가 되었고, 체계적인 프로세스에 따라 결정을 했다는 생각에 그냥 결정을 내릴 때보다 결정에 대한 불안감이 줄어들었다. 저자가 설명한 내용 중 내가 정리한 내용을 바탕으로 아래에 현명한 의사결정 프로세스에 대해 설명하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 선택안 넓히기(Widen options)&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 의사결정에선 선택안을 넓히는 것이 중요하다. 우리는 생각보다 더 많은 선택안이 있을 수도 있다는 사실을 간과하곤 한다. 예컨대, 본인이 CEO이고 사내 CS(Customer Service)팀에 A라는 직원이 있다고 해보자. 해당 직원은 정해진 일을 기한에 맞춰서 하거나 복잡한 자료들을 체계적으로 정리해 보고서를 작성하는 일은 굉장히 잘한다. 하지만 인간관계에서의 커뮤니케이션 스킬이 약해서 동료들이나 고객과의 관계에선 트러블이 많다. 당신이라면 이 직원을 어떻게 하겠는가? 이에 대한 답은 대부분 안타깝지만 해당 팀에서 근무하기에는 적합하지 않은 것 같아서 해고를 한다 혹은 다른 일을 잘하니까 조금 더 데리고 있으면서 살펴본다로 나뉘곤 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 하지만 선택안이 정말 그 둘 뿐일까? 커뮤니케이션 스킬은 약하지만 착실히 일을 하는 직원이고, 게다가 기한을 잘 맞추고 복잡한 자료에 대한 체계적인 정리와 보고서를 작성하는 능력이 뛰어난 것은 사실이다. 그렇다면 해고할지 말지를 두고 고민하기보단 장점을 살릴 수 있는 총무팀과 같은 곳에 배치하는 것은 어떨까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이처럼 우리는 고민을 하는 상황에서 시야가 좁아져 다른 대안들을 검토하지 못하고 그 당시에 최선이라고 생각하는 두 가지 중에 고민하는 경우가 많다. 특히 경계해야할 것으로는 &quot;A를 할지 말지&quot;와 같은 &lt;b&gt;가부결정&lt;/b&gt;으로 사항을 고정시켜버리는 것이다. 이는 A에 대해서만, 그리고 그것을 할지 말지에 대해서만으로 선택의 범위와 시야를 제한시킨다고 한다. 보다 나은 선택안 탐색을 위해 저자는 다음과 같이 생각해볼 것을 추천한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. A를 할 시간과 노력으로 &lt;b&gt;다른 것은 무엇을 할 수 있을까?&lt;/b&gt;(기회비용 생각해보기)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 고민 중인 A와 B를 &lt;b&gt;모두 할 수 없다면&lt;/b&gt; 어떻게 할 것인가?(제한적인 상황에서 창의적인 대안 모색)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. A와 B를 &lt;b&gt;동시에&lt;/b&gt; 할 수 있는 방법은 없나?(생각보다 같이 할 수 있는 경우가 많음에도 불구하고 우리는 둘 중 한 가지만을 선택하려고 한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 확증편향에서 벗어나기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 대부분의 사람들은 자신의 고민에 대해서는 쉽사리 결정을 내리지 못한다. 하지만, 친구나 후배에게 조언을 해줄 때를 떠올려보면 우리는 생각보다 쉽게 해결책을 제시해주곤 한다. 이는 자신의 문제에 대해서는 많은 가능성과 변수들을 고려하며 정작 가장 중요한 것에 초점을 맞추지 못하기 때문이라고 한다. 하지만 타인의 문제에 대해서는 자신의 일만큼 많은 것들을 고려하지 않다보니 오히려 &lt;b&gt;&quot;가장 중요한 부분&quot;&lt;/b&gt;에 집중해 결정을 내릴 수 있는 것이다. 이를 역이용하여 저자는 다음과 같이 생각해보길 권한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&quot;나의 가장 친한 친구라면 나는 무슨 조언을 했을까?&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&quot;내가 이 자리에서 물러나고 나의 후임자가 들어온다면 어떤 결정을 했을까?&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. 거리감 두기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 서두에 언급했 듯이 인간은 감정의 동물이기에 선택의 순간에 감정이 개입되기 마련이다. 물론, 감정이 중요하지 않은 것은 아니다. 때때로 순간의 감정은 단기적인 선택에서 자신이 진정으로 원하는 것이 무엇인지를 알 수 있게 해준다. 하지만 장기적인 관점을 두고 선택을 해야하는 상황에서 감정에 휘둘려 결정을 내리는 것은 그리 좋지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 저자는 결정과 자신을 분리해서 객관적으로 바라보아야 한다고 말한다. 이를 위한 효과적인 방법은 &lt;b&gt;결정을 내리고나서 10분 후, 10개월 후, 10년 후 어떤 감정일까?를 생각해보는 것&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 책에서 나온 예시를 소개한다. A는 현재 사귀고 있는 B에게 결혼에 대해 얘기하려고 한다. A는 결혼을 원하고 있지만 B는 어째서인지 한 동안 결혼에 대한 이야기에 대해 진전이 없었다. B는 이미 이혼을 하여 아이가 있는 상황이었고 그래서인지 결혼에 대한 두려움을 크게 느끼고 있는 듯하다. A는 자신도 점차 나이를 먹어가는데 언제까지나 사귀는 사이로 남을 수는 없다고 생각한다. 하지만 결혼에 대한 얘기를 꺼내기가 쉽지 않아 고민을 하고 있다. 이 때 A가 B에게 결혼에 대해 이야기를 꺼내기로 결정을 했다고 해보자. 만약 본인이 A라면 10분 후, 10개월 후, 10년 후 해당 결정에 대해 어떻게 생각하게 될지를 써보는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;10분 후 : 괜히 이야기를 꺼냈나...? 그냥 지금처럼 서로 행복하면 된 것을. 그대로 사귀는 사이를 유지할 걸...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;10개월 후 : 만약 그 때의 결정을 통해 B도 용기를 내어 결혼을 하게 되었다면 정말 행복할 것이고, 반대의 경우라면 마음이 아프지만 그래도 이야기를 꺼내 B가 결혼 생각이 없다는 것을 알게되었기에 자신의 결정을 후회하지는 않을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;10년 후 : B와 헤어졌다면 10년 전의 결정에 대해선 크게 생각하지 않으며(어쩌면 잊거나) 이미 다른 사람과 잘 살고 있을 수도 있다. 그게 아니라면 B와 결혼해 행복하게 잘 살고 있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 나누어 생각해보면 어느 모로 보나 A는 자신의 입장에서 결혼에 대한 이야기를 B에게 꺼내보는 것이 이득이다. 이 같은 방식은 결정에 대해 깊게 매몰되어 감정에 휘둘리는 상황에서 벗어나게 해준다. 10개월 후, 10년 후에 어떻게 생각할까를 적어보면 우리는 선택에 대해 자연스레 거리감을 두고 한 발 떨어져 바라볼 수 있게 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4. 실패에 대비하라&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 결정을 하였다면 실패의 비용을 준비하는 것이 좋다. 이를 위해선 &lt;b&gt;인계철선&lt;/b&gt;을 설정해야 한다. 책에서는 다른 말로 &lt;b&gt;북엔드(Bookend)&lt;/b&gt;라고도 한다. 책꽂이에 책을 세워둘 때 책이 무너지지 않게 양쪽 끝을 지지해주는 것이다. 주목해야 할 점은 한 쪽 끝이 아닌 &lt;b&gt;양쪽 끝&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 우리가 착각하고 있는 사실은, 성공과 실패가 시간의 수평선 상에 하나의 점으로 나타난다는 생각이다. 하지만 성공과 실패의 순간은 범위(range)로 나타나는 경우가 훨씬 많다. 사업을 예로 들면 하루 아침에 성공하기 보단 조금씩 고객의 수가 늘어나기 시작하다가 폭발적으로 늘고, 판매지역이 확장되어 사업의 규모가 커진다. 실패의 경우도 마찬가지다. 어느 한 순간 실패한다기보다는 점차 사용하는 고객의 수가 줄어들고(초반에는 눈치채지 못할 정도로 작은 규모로) 이것이 쌓이고 쌓이다 자신이 운영하는 회사의 제품과 유사하지만 단점을 개선한 더 나은 제품이 출시되어 시장에서 밀리게 된다. 이처럼 성공과 실패는 하나의 점이 아니라 일정 range로 나타난다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이러한 range 안에서 우리는 각자가 설정한 기준에 따라 지금 성공의 range에 들어가 있는 것인지, 실패의 range안에 들어가려고 하는 것인지를 판단해 의사결정을 내려야 한다. 자신이 내린 결정에 대해 어느 정도의 성과가 있을 때 성공으로 간주하고 다음 스텝으로 넘어갈지, 어느 정도의 손실이 있어야 결정을 철회하고 다른 대안을 모색할지를 정해두어야 한다. 새로운 사업을 하려고 한다면, 초기 예산 얼마 정도로 어느 정도의 성과를 내는 것을 목표로 할지를 정해야 한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 만약 1000만원을 초기비용으로 잡았는데 500만원을 사용한 상태에서 고객이 1명도 없는 상황이라고 가정해보자. 이런 경우 아직 1000만원에서 500만원이 남았기 때문에 조금 더 해봐도 괜찮겠다는 생각을 할 수 있다. 하지만 이러한 북엔드를 정해두지 않은 상황에선 아직까지도 고객이 없다는 사실에 초조해지기 쉽다. 성공의 경우에도 적절한 인계철선을 설정하는 것이 중요하다. 대부분의 경우에 처음에 생각했던 것과는 다른 방향으로 성공을 거두기도 하기 때문이다. 넷플릭스(Netflix)는 처음에 우편물로 DVD를 대여해주는 서비스로 시작하였다. 이로부터 점차 점차 시장 지표를 보고 조금씩 사업방향을 수정하여 현재의 모습에 이른 것이다. 성공과 실패에는 운이라는 요소가 많이 작용하지만, 이 또한 기회를 잡는 사람에게 주어지는 것이다. 이런 기회를 적절한 때에 잘 잡기 위해서는 자신이 현재 성공하는 range에 들어와있는 상태인지에 대한 나름의 평가기준을 세워두고 이에 따라 의사결정을 내려야 하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 그저 뻔한 이야기만을 서술하지 않고, 실질적으로 의사결정을 잘 하기 위한 프로세스를 세세하게 소개해주는 책이다. 책에는 각 챕터에 대한 많은 예시들이 나온다. 이를 보고 자신의 상황에 적용시켜보며 읽으면 중요한 결정을 내리는데에 도움이 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>도서</category>
      <category>감상평</category>
      <category>결정하는법</category>
      <category>댄히스</category>
      <category>생각에 관한 생각</category>
      <category>선택장애</category>
      <category>의사결정</category>
      <category>자신있게 결정하라</category>
      <category>칩히스</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/388</guid>
      <comments>https://otugi.tistory.com/388#entry388comment</comments>
      <pubDate>Sun, 30 Oct 2022 17:01:20 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2143] 두 배열의 합 - 파이썬(Python)</title>
      <link>https://otugi.tistory.com/387</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2143&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2143&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664002445640&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2143번: 두 배열의 합&quot; data-og-description=&quot;첫째 줄에 T(-1,000,000,000 &amp;le; T &amp;le; 1,000,000,000)가 주어진다. 다음 줄에는 n(1 &amp;le; n &amp;le; 1,000)이 주어지고, 그 다음 줄에 n개의 정수로&amp;nbsp;A[1], &amp;hellip;, A[n]이 주어진다. 다음 줄에는 m(1 &amp;le; m &amp;le; 1,000)이 주어지고, 그&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2143&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2143&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/efSrxd/hyPT2e6qfv/Ekkiyx5PXkJr1AUscTEP10/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2143&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2143&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/efSrxd/hyPT2e6qfv/Ekkiyx5PXkJr1AUscTEP10/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2143번: 두 배열의 합&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 T(-1,000,000,000 &amp;le; T &amp;le; 1,000,000,000)가 주어진다. 다음 줄에는 n(1 &amp;le; n &amp;le; 1,000)이 주어지고, 그 다음 줄에 n개의 정수로&amp;nbsp;A[1], &amp;hellip;, A[n]이 주어진다. 다음 줄에는 m(1 &amp;le; m &amp;le; 1,000)이 주어지고, 그&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;단순히 두 배열의 합을 구해 일일히 비교하면서 합이 T가 되는지 구해보는 방식은 O(n^2m^2)만큼의 시간복잡도가 걸려서 통과되지 않는다. 연산시간을 줄여야 하는데 A의 부분합에 대한 dictionary를 만든 뒤 (T-B의부분합)이 A의 부분합 dictionary 내에 있는지 파악해 가짓수에 더해주어야 한다. 이렇게 하면 딕셔너리의 원소 액세스 시간복잡도 O(1)이라는 이점을 이용해 연산 시간을 줄일 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1664002584994&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/2143

import sys
input = sys.stdin.readline
from collections import defaultdict

T = int(input())
n = int(input())
A = list(map(int, input().split()))
m = int(input())
B = list(map(int, input().split()))

ans = 0
A_dict = defaultdict(int)

for i in range(n):
    for j in range(i, n):
        A_dict[sum(A[i:j+1])] += 1

for i in range(m):
    for j in range(i, m):
        ans += A_dict[T - sum(B[i:j+1])]

print(ans)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>PYTHON</category>
      <category>두 배열의 합</category>
      <category>백준</category>
      <category>백준 2143</category>
      <category>부부합</category>
      <category>알고리즘</category>
      <category>이분탐색</category>
      <category>코딩 테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/387</guid>
      <comments>https://otugi.tistory.com/387#entry387comment</comments>
      <pubDate>Sat, 24 Sep 2022 15:56:58 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2239] 스토쿠 - 파이썬(Python)</title>
      <link>https://otugi.tistory.com/386</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2239&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664000405781&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2239번: 스도쿠&quot; data-og-description=&quot;스도쿠는 매우 간단한 숫자 퍼즐이다. 9&amp;times;9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3&amp;times;3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2239&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2239&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dkInqP/hyPT0VRzel/oDGX5jGSdOEtC27GdaRnkK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/RZ464/hyPTZJpF4g/pjMHhBc3A824g14qLOBqi1/img.png?width=341&amp;amp;height=337&amp;amp;face=0_0_341_337&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2239&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dkInqP/hyPT0VRzel/oDGX5jGSdOEtC27GdaRnkK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/RZ464/hyPTZJpF4g/pjMHhBc3A824g14qLOBqi1/img.png?width=341&amp;amp;height=337&amp;amp;face=0_0_341_337');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2239번: 스도쿠&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스도쿠는 매우 간단한 숫자 퍼즐이다. 9&amp;times;9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3&amp;times;3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;u&gt;백트래킹&lt;/u&gt;을 사용해서 탐색을 해주면 된다. 검사할 항목은 가로, 세로, 3x3 사각형 안에 사용된 숫자들이 무엇인지이다. 이를 c1, c2, c3에 기록해두고 겹치지 않는 숫자 candidate들을 하나씩 넣어보면서 조건에 위배되는지를 살펴보고 위배된다면 백트래킹으로 다시 값들을 복구하고 다음 후보 숫자를 넣어 탐색하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1664000420041&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/2239

def cal(x,y):
    return (x//3)*3 + (y//3)

def sol(n):
    if n == 81:
        for a in A:
            print(''.join(list(map(str, a))))
        return True
    x = n // 9
    y = n % 9
    if A[x][y]:
        return sol(n+1)
    else:
        for i in range(1,10):
            if not c1[x][i] and not c2[y][i] and not c3[cal(x,y)][i]:
                c1[x][i] = c2[y][i] = c3[cal(x,y)][i] = True
                A[x][y] = i
                if sol(n+1):
                    return True
                c1[x][i] = c2[y][i] = c3[cal(x,y)][i] = False
                A[x][y] = 0
    
    return False

A = [list(map(int, input())) for _ in range(9)]
c1 = [[False]*10 for _ in range(9)] # row
c2 = [[False]*10 for _ in range(9)] # col
c3 = [[False]*10 for _ in range(9)] # 3x3 square
for i in range(9):
    for j in range(9):
        if A[i][j]:
            c1[i][A[i][j]] = True   # i행에 A[i][j] 숫자가 사용됨
            c2[j][A[i][j]] = True   # j열에 A[i][j] 숫자가 사용됨
            c3[cal(i,j)][A[i][j]] = True # cal(i,j)번째 square에 A[i][j] 숫자가 사용됨
sol(0)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Reference : &lt;/span&gt;&lt;a href=&quot;https://hazung.tistory.com/153&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;https://hazung.tistory.com/153&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>backtracking</category>
      <category>PYTHON</category>
      <category>그래프탐색</category>
      <category>백준</category>
      <category>백준 스도쿠</category>
      <category>백트래킹</category>
      <category>스도쿠</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/386</guid>
      <comments>https://otugi.tistory.com/386#entry386comment</comments>
      <pubDate>Sat, 24 Sep 2022 15:22:06 +0900</pubDate>
    </item>
    <item>
      <title>취직과 이직을 위한 소소한 팁, 취준과 이직을 준비하는 시기에 알았으면 좋았을 것들</title>
      <link>https://otugi.tistory.com/385</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 취직 혹은 이직은 누구에게나 힘든 일일 것이다. 나 또한 처음 취준을 하던 시기와 이직을 하던 시기에 많이 힘들었던 기억이 난다. 지금 생각해도 정말 돌아가고 싶지 않을 정도로. 시간이 지나고나서 든 생각은 누군가가 나에게 어떠한 마인드로 준비를 하면 되는지라던가 소소한 팁들을 알려주었다면 준비하는 기간이 조금은 더 짧아질 수도 있지 않았을까였다. 취업이나 이직을 준비하는 누군가에게 도움이 될까하는 마음으로 느꼈던 몇가지를 적어본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 되도록 많은 곳에 지원해라&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 취직은 결국 &quot;전략&quot; 싸움임을 인지하는 것이 중요하다. 주변에서 &quot;딱 한군데만 지원했는데 운 좋게 붙었어요.&quot;와 같은 말을 들어본 적이 있을 것이다. 좀 배가 아프지만 채용이라는게 사실 그렇다. 나는 이 사실을 알기까지 굉장히 많은 시간이 걸렸던 것 같다. 여러 회사의 면접을 보고나서 느낀 점은 &lt;u&gt;채용이라는게 사실은 매우 주관적일 수 있다&lt;/u&gt;는 것이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이직을 준비하던 시기에 정말 많은 기업의 면접을 보았다. 어느 회사의 면접을 보았을 때, 나는 그다지 좋지 않은 평가를 받았었다. 낙담해서 좌절하고 있던 순간 다른 회사의 면접 일정이 잡히게 되었다. 그런데 해당 회사에서는 매우 좋은 평가를 받았고, 당시 찾고 있던 인력과 잘 맞는 것 같다는 얘기를 들어 내 경력으로는 생각도 못할 직급으로 오퍼를 받기도 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이처럼 면접은 결국엔 사람이 사람을 뽑는 것이기에 근본적으로 모든 곳에서의 평가가 동일할 수 없다. 그러니 어느 한 곳에서 부정적인 평가를 받았다고 해서 쉽게 좌절하거나 포기하지 말아야 한다. 한국에서 자라 성적순으로 줄세우는 식의 평가에만 익숙해져 있던 나는 그러한 사고방식에 사로잡혀 한 곳에서 좋지 않은 평가를 받았다는 것이 절대적으로 내 실력이 모자라 다른 곳에 지원할 수 없음을 나타내는 거라고 생각했다. 그러나 채용은 단순히 성적순으로 나열하는 입시와는 다르다. 본인이 면접을 보는 날, 해당 시간대에 배정된 면접관과 합이 잘 맞아서 대화가 잘 이루어져 그 분들로부터 긍정적인 평가를 얻어내야 하고, 회사의 culture fit과도 잘 맞아야 한다. 또한 본인이 apply하는 시점의 해당 position의 구체적인 사항이 자신의 경력사항이나 보유하고 있는 기술스택과 잘 맞아야 한다. 사실 이러한 부분은 직접 부딪혀보기 전까지는 알기 어려운 경우가 많다. &lt;u&gt;그러니 가능한 많은 곳에 apply해보는 것이 확률을 높이는 방법이다.&lt;/u&gt; 결국은 확률 싸움인 셈이다. 채용에 있어서 생각보다 많은 부분에서 운이 작용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. &quot;반드시 내가 원하는 곳에 가야지&quot;라는 생각을 접어라&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이 부분은 어느 곳이든 지원하면 붙어서 골라갈 수 있는 능력이 있는 사람들에겐 해당사항이 없다. 누구나 취직을 준비하며 본인이 꼭 가고 싶은 곳이 한 군데씩은 있을 것이다. 나 또한 그러했고, 내가 생각지도 못할만큼 괜찮은 기업에 서류 합격을 하면서는 그러한 생각이 더 커져만 갔다. 그래서인지 너무나 많은 기대감을 해당 기업의 결과에 걸게 되었고, 결과적으로 이는 다른 곳의 면접 준비에 소홀하게 만들고 탈락했을 때 더 많은 좌절감을 안겨주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 지금 와서 돌이켜보면, &lt;u&gt;&quot;나는 반드시 내가 원하는 곳에 가야지!&quot;라는 생각은 좋은 동기가 될 수는 있지만 이 생각에만 사로잡히는 것은 오히려 구직 기간을 더 늘리는 요인이 되는 것 같다&lt;/u&gt;. 이는 여러 곳에 합격한 뒤에 그 중에서 본인이 원하는 곳에 가야지!라는 생각과는 다르다. 1번에서 언급한 내용과 어느 정도 같은 맥락이긴 한데, &quot;내가 뛰어나게 잘하는 모습을 보이고, 절대적인 실력을 높여서 반드시 원하는 곳에 가야지!&quot;라는 생각은 사실 이를 평가하는 사람이 따로 있다는 사실을 객관적으로 바라보지 못하는 데서 비롯되는 것 같다. 정말 많은 기업에 지원해서 여러 번 면접을 보다보면 결국 자신과 맞는 곳이 반드시 있고, 어딘가에서는 본인 같은 사람을 필요로 한다는 사실을 알게 된다. 왜냐하면 결국 채용이란 것이 사람이 사람을 뽑는 일이기 때문이다. 쉽게 말해 우리 모두가 주변의 모든 사람들과 합이 잘 맞을 수 없듯이 면접 시에 마주하는 모든 기업의 면접관들과 합이 잘 맞을수는 없기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 본인이 사회 초년생이거나 경력이 많지 않은 사람이라면 더더욱 이 같은 생각을 빨리 버리는 것이 도움이 될 수 있다. IT 분야 현업에서는 경력이 굉장히 중요하다. 지금 당장은 본인이 생각하는 기대치에 맞지 않더라도 경력을 쌓아서 백그라운드를 만들어둔 뒤에 더 높은 곳으로 이직할 수 있는 기회가 얼마든지 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. 외국계 기업을 노려봐라&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 결과적으로 나는 3군데의 외국계 기업에 최종적으로 합격하게 되었다(대학원에 진학하게 되어 해당 기업들에 가진 않았지만). 처음 취준과 이직을 하던 시기에 나는 한국 기업들에만 지원하였다. 단순히 외국계 기업은 내가 지원하기에는 허들이 너무 높다고만 생각하였다. 하지만 지금 돌아간다면 조금 더 일찍 외국계 기업들에 지원해볼 것 같다. 국내에서 많이 알려지진 않았지만 세계적으로 괜찮은 외국계 기업들이 한국에도 정말 많다. 이러한 기업들은 보통 AWS Korea, Intel Korea 등과 같이 한국 지사를 둔 곳으로 apply하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 한국계와 외국계 기업들의 면접을 여러 번 보았는데, 개인적인 생각으로는 한국계 기업의 채용 프로세스가 좀 더 빡세고 기준이 높았던 것 같다. 물론 이는 1번에서 말한 것과 같이 본인의 성향에 따라 다르게 느낄 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 한국계 기업의 경우 일반적인 CS 전공 지식을 물어보는 곳이 많았다. 가령 OS의 역할이라던가, 쓰레드가 무엇인지, 메모리의 종류에 대해 설명해보시오 등이었다. 외국계 기업도 이러한 질문을 안하는 것은 아니지만 뭐랄까...&lt;u&gt;조금 더 지원자 개인에게 초점을 맞춘 질문&lt;/u&gt;들을 많이 받았던 것 같다.(레쥬메를 정말정말 자세히 읽어본다.) 지원자의 경력사항이나 개인적으로 만든 프로젝트에 대해 매우 심도있는 질문들을 받았다. 직접 만들어본 경험이 없다면 설명하기 어려운 정도로 말이다. 또한 한국계 기업보다는 culture fit을 많이 보는 것 같았다. 확실히 인성 면접과 관련된 부분들은 한국계 기업보다 면접에서 대답하기가 훨씬 어렵고 힘들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 어쨌든 핵심은, 외국계 기업의 경우 한국계 기업과는 확실히 다른 쪽에 포커스를 두고 채용을 진행한다는 것이다. 때문에 사람의 성향에 따라서는 한국계 기업과는 확연히 다른 외국계 기업의 채용 프로세스에 더 강점을 보일 수도 있다. 채용에서 뽑히고 말고는 결국 내가 그 채용 과정과 잘 맞아서 긍정적인 평가를 받으면서 끝까지 도달하느냐의 여부와 관련이 있으니까 이는 굉장히 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4. 지원할 순서를 고려하라&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 아까 서두에서 취업은 &quot;전략&quot;싸움이라는 말을 했었다. 지원을 하는 순서를 정하는 것 역시 이러한 전략에 포함된다. 대부분의 사람들이 상향지원순으로 기업에 지원하라는 말들을 많이 한다. 하지만 나는 생각이 조금 다르다. &lt;u&gt;상향순 지원과 하향순 지원은 각각의 장단점이 분명히 있다.&lt;/u&gt; 이를 고려하고 본인에게 맞는 순서대로 지원하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 상향순으로 지원하는 것에 대해 먼저 언급하고자 한다. 1번에서 언급한 것과 같이 많은 곳에 지원을 해보면 생각보다 자신이 많은 곳에 붙기도 한다는 걸 알게 된다. 이러한 경우 한 번에 여러 기업들과 절차에 따라 면접 일자를 잡아야 하거나 기업에서 이야기하는 고정된 날짜에 면접을 봐야하는 경우가 생긴다. 만약 본인이 두 군데 이상의 기업과 면접 절차를 진행 중이라고 한다면 이 날짜를 잡는 것과 최종 결과 발표일에 대해 신경을 써야 하는 경우가 생긴다. 두 군데 중 좀 더 높은 곳의 최종합격 발표 일자가 좀 더 빠르다면 해당 기업의 합격 여부를 보고 다른 기업의 나머지 절차를 더 이상 진행하지 않을 선택권이 생긴다. 하지만 그 반대의 경우라면 머리가 복잡해진다. 더 높은 곳의 채용절차는 아직 남아있는데 해당 기업에 내가 합격할 수 있을지에 대한 여부를 모르는 상황에서 다른 기업의 채용절차가 마감되어 오퍼를 받아 계약서에 서명을 할지 여부를 결정해야 한다. 이처럼 복잡하고 입장이 난처한 여러 상황이 생길 수 있으므로 상향순으로 지원해서 좀 더 기준이 높은 기업의 결과를 보고 결정하는 것이 편할수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 하지만 하향순으로 지원하는 것에도 분명한 장점이 있다. 실제로 나는 하향순으로 지원을 했고, 그 결과 시간이 지날수록 점차 많은 곳에 합격을 할 수 있었고, 좀 더 높은 곳의 기업 면접도 비교적 수월하게 치를 수 있었다. 면접이라는게 본질적으로 사람을 상대하는 일이고, 자신의 생각을 조리있게 말해야 하는 과정이다. 이러한 능력은 여러 번 반복하고, 비슷한 환경에 노출될수록 스킬이 올라가기 마련이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 실제로 나는 면접을 보고나서 쉬지않고 바로 해당 면접에서 나왔던 질문들 중 내가 제대로 답변하지 못했던 것들을 복기하여 기록해두었다. 그리고 해당 질문들에 대한 답을 찾아 따로 기록해두고, 나만의 면접 오답노트를 작성하였다. 또한 인성면접 질문에서 내가 제대로 말하지 못했던 부분에 대해서는 나의 생각을 다시 정리해두었고, 좀 더 매끄럽게 대답하기 위한 plot을 재구성하였다. 많은 기업에서 면접을 보다보면 사람들이 갖게되는 생각이 꽤나 비슷하고 물어보는 질문들이 어느 정도 정형화 되어있다는 것을 알 수 있다. 고정된 하나의 레쥬메를 보고 면접관이 전혀 예상하지 못한 완전히 새로운 질문을 떠올리는 경우는 사실 거의 없기 때문이다. 그래서 자신이 작성한 레쥬메를 보고 타인이 갖게 되는 질문사항들에는 어느 정도 교집합이 있다. 이러한 부분들을 잘 공략하면 효율적으로 면접에 대한 준비를 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이같은 훈련이 실제로 매우 효과가 있었다. 면접을 보면 볼수록 나는 나의 생각을 좀 더 조리있게 말하게 되었고, 경력사항이나 사용해본 기술스택에 대한 설명도 전보다 자세히 설명할 수 있게 되었다. 아마 그래서 뒤로 갈수록 점점 더 기준이 높은 기업에 많이 붙게 되었고, 비교적 수월하게 면접을 치를 수 있었던 것 같다. 뿐만 아니라 면접이라는 심리적 압박감이 큰 상황에 반복적으로 노출되었던 것은 두려움이라는 감정을 없애는데에도 많은 도움이 되었다. 위에서 언급했듯이 면접이라는 것이 근본적으로 사람을 상대하는 일이기에 두려움이나 초조함과 같은 감정에 사로잡혀 중언부언하며 생각을 제대로 전달하지 못하면 평가를 하는 사람들에게 좋은 인상을 주기가 어렵다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 상향순, 하향순 중 어떠한 것을 따르라고 말하지는 않겠다. 하지만 각각의 장단점이 분명히 있으니 &lt;u&gt;본인의 성향을 고려하여 둘 중 조금 더 유리한 방향으로&lt;/u&gt; 지원하는 것이 좋겠다. 나는 내 실력에 자신이 있고, 여러 기업들의 면접 절차나 오퍼 수락과 관련해 난처한 상황이 생기는게 싫다면 상향순으로 지원을 하면 된다. 반대로 면접에 정말 자신이 없거나, 어떻게 준비해야할지 모르는 상황이라면 하향순으로 지원하는 것이 도움이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;돌이켜보면, 나는 이러한 것을 알려줄 사람이 없었어서 그저 몸으로 부딪혀가며 익혔다. 나와 같은 마음으로 고생하고 있을 누군가에게 도움이 되었으면 하는 마음으로 느낀 점을 정리해보았다.(도움이 될지 모르겠지만...) 모두가 원하는 기업에 취뽀를 하고 웃을 수 있기를 바라며.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>땅어일기</category>
      <category>It</category>
      <category>IT기업 이직</category>
      <category>개발자</category>
      <category>개발자 이직</category>
      <category>개발자 취업</category>
      <category>이직</category>
      <category>이직 팁</category>
      <category>취준</category>
      <category>취준 팁</category>
      <category>취직</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/385</guid>
      <comments>https://otugi.tistory.com/385#entry385comment</comments>
      <pubDate>Tue, 20 Sep 2022 23:40:16 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2473] 세 용액 - 파이썬(Python)</title>
      <link>https://otugi.tistory.com/384</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2473&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2473&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662710153387&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2473번: 세 용액&quot; data-og-description=&quot;첫째 줄에는 전체 용액의 수 N이 입력된다. N은 3 이상 5,000 이하의 정수이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2473&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2473&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dmeDli/hyPJ6PbYyI/hUthIW329iBw0eShutcK9K/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2473&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2473&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dmeDli/hyPJ6PbYyI/hUthIW329iBw0eShutcK9K/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2473번: 세 용액&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에는 전체 용액의 수 N이 입력된다. N은 3 이상 5,000 이하의 정수이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그냥 n개의 원소 중 임의의 3개를 뽑아서 합을 구하는 방식으로 하게 되면 시간복잡도가 O(n^3)까지 올라가게 된다. 따라서 투 포인터를 사용해서 O(n^2)으로 풀어야 통과할 수 있다. i를 0~n-2까지 순회하면서 left와 right를 바꿔주어야 한다. 아래 코드는 python으로는 시간초과가 나왔고 pypy로 통과하였다. 서치를 해보니 대부분의 해답들이 pypy로 제출해 통과하였고, python으로 제출해 통과하려는 경우엔 iter를 사용해 좀 더 python스럽게 코드를 작성해야 한다.(하지만 이게 본 문제 알고리즘 풀이의 핵심이 아니므로 넘어가도록 한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;392&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boyDxY/btrLNvsKdZX/pSZt0neh4BSjbyYuDHvYV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boyDxY/btrLNvsKdZX/pSZt0neh4BSjbyYuDHvYV1/img.png&quot; data-alt=&quot;투 포인터(그림 출처 : cieske tistory)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boyDxY/btrLNvsKdZX/pSZt0neh4BSjbyYuDHvYV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboyDxY%2FbtrLNvsKdZX%2FpSZt0neh4BSjbyYuDHvYV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;392&quot; height=&quot;138&quot; data-origin-width=&quot;392&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;투 포인터(그림 출처 : cieske tistory)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1662710338309&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/2473
import sys
input = sys.stdin.readline

N = int(input())
arr = list(map(int, input().strip().split()))
arr.sort()
ans = [0, 0, 0]
res = float('inf')

for i in range(N-2):
    l, r = i+1, N-1
    while l &amp;lt; r:
        curr = arr[i] + arr[l] + arr[r]
        if abs(curr) &amp;lt; abs(res):
            ans = [arr[i], arr[l], arr[r]]
            res = curr
        if curr &amp;gt; 0:
            r -= 1
        elif curr &amp;lt; 0:
            l += 1
        else:   # curr == 0
            print(arr[i], arr[l], arr[r])
            sys.exit()
for num in ans:
    print(num, end=' ')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>Algorithm</category>
      <category>PYTHON</category>
      <category>두 포인터</category>
      <category>백준</category>
      <category>백준 세 용액</category>
      <category>솔브드</category>
      <category>알고리즘</category>
      <category>코딩 테스트</category>
      <category>투 포인터</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/384</guid>
      <comments>https://otugi.tistory.com/384#entry384comment</comments>
      <pubDate>Fri, 9 Sep 2022 17:01:03 +0900</pubDate>
    </item>
    <item>
      <title>[백준 20040] 사이클 게임</title>
      <link>https://otugi.tistory.com/382</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #4a4a4a;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/20040&quot;&gt;https://www.acmicpc.net/problem/20040&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;color: #4a4a4a;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;figure id=&quot;og_1660724963110&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;20040번: 사이클 게임&quot; data-og-description=&quot;사이클 게임은 두 명의 플레이어가 차례대로 돌아가며 진행하는 게임으로, 선 플레이어가 홀수 번째 차례를, 후 플레이어가 짝수 번째 차례를 진행한다. 게임 시작 시 0 부터 n &amp;minus; 1 까지 고유한 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/20040&quot; data-og-url=&quot;https://www.acmicpc.net/problem/20040&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beyaYx/hyPuKSZCad/zH8tRbej0LpOkSVVkDqZb0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/20040&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/20040&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beyaYx/hyPuKSZCad/zH8tRbej0LpOkSVVkDqZb0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;20040번: 사이클 게임&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;사이클 게임은 두 명의 플레이어가 차례대로 돌아가며 진행하는 게임으로, 선 플레이어가 홀수 번째 차례를, 후 플레이어가 짝수 번째 차례를 진행한다. 게임 시작 시 0 부터 n &amp;minus; 1 까지 고유한&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전형적인 유니온 파인드(union find) 문제이다. 유니온 파인드 알고리즘은 그래프가 사이클을 갖는지 여부를 판별하는 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;약간 헷갈렸던 부분이 사이클을 판별하기 위해선 연결하려는 두 노드 x,y가 같은 부모를 갖는지를 먼저 확인하고 unionParent 함수를 call해야 된다는 점이다. 처음에 unionParent를 먼저 실행하고 isSameParent를 실행했다가 틀렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파이썬의 경우 재귀 함수의 최대 깊이로 인해 처음 제출하면 Runtime error가 나는데 setrecursionlimit을 설정해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1660725036757&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/20040
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline

def getParent(x):
    if parent[x] == x:
        return x
    else:
        parent[x] = getParent(parent[x])
        return parent[x]

def unionParent(x,y):
    x_parent = getParent(x)
    y_parent = getParent(y)
    if x_parent &amp;lt; y_parent:
        parent[x_parent] = y_parent
    else:
        parent[y_parent] = x_parent

def isSameParent(x,y):
    if getParent(x) == getParent(y):
        return True
    else:
        return False

node, turn = map(int, input().split())
edge = []
for _ in range(turn):
    edge.append((tuple(map(int, input().split()))))
parent = [i for i in range(node)]
cnt = 0
done = False
for x,y in edge:
    cnt += 1
    if isSameParent(x,y):
        print(cnt)
        done = True
        break
    unionParent(x,y)
if not done:
    print(0)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>BOJ</category>
      <category>cycle detection</category>
      <category>PYTHON</category>
      <category>union find</category>
      <category>백준</category>
      <category>백준20040</category>
      <category>사이클 게임</category>
      <category>사이클 찾기</category>
      <category>유니온파인드</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/382</guid>
      <comments>https://otugi.tistory.com/382#entry382comment</comments>
      <pubDate>Wed, 17 Aug 2022 17:32:46 +0900</pubDate>
    </item>
    <item>
      <title>아나콘다 환경 복사하기(export, clone, Anaconda)</title>
      <link>https://otugi.tistory.com/381</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아나콘다(Anaconda)를 사용하다보면 같은 환경을 &lt;b&gt;다른 머신에서도 사용&lt;/b&gt;하고 싶거나, &lt;b&gt;같은 머신에서 비슷한 환경을 복제한 뒤 이런저런 패키지를 추가, 삭제하여 사용&lt;/b&gt;하고 싶은 경우가 있다. 이를 위한 기능이 콘다에 있다. 즉, 일일히 패키지를 설치하지 않아도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #1 : Conda env를 yaml 파일로 export 하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래와 같이 자신이 복제하고자 하는 콘다 가상환경을 activation 시킨 뒤 &lt;b&gt;conda env export&lt;/b&gt; 명령어를 사용해서 해당 콘다 환경을 yaml 파일로 저장해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660629745741&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda activate myconda	# 만약 가상환경 이름이 myconda라면
conda env export &amp;gt; myconda.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;두번 째 명령어를 실행하면 yaml 파일에 자신의 콘다 가상환경에 대한 정보가 저장되는데 해당 yaml 파일을 열어보면 name 키의 값은 가상환경의 이름, &lt;b&gt;dependecies&lt;/b&gt; 키의 값은 설치될 여러 패키지들이 버전과 함께 쓰여져 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;새로 생성되는 가상환경의 이름은 &lt;b&gt;name&lt;/b&gt; 키의 값으로 만들어지므로 만약 본인이 같은 머신 내에서 환경을 복사하고자 하는 것이라면 이 name 키의 값을 바꾸어 중복이 되지 않게 해주어야 한다.(다른 머신이라면 애초에 문제가 없으니 건너 뛰어도 된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또한 &lt;b&gt;prefix&lt;/b&gt; 키에는 가상환경이 설치될 디렉토리가 값으로 쓰여져 있는데 name을 바꾼 뒤 prefix의 값도 바꾸어줘야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다른 머신에 콘다 환경을 설치하고자 하는 거라면 바로 이 &lt;u&gt;yaml 파일을 해당 머신으로 전송한 뒤&lt;/u&gt; 위의 명령어로 설치해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #2 : yaml 파일로 콘다 환경 생성하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1660629919677&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda env create -f myconda.yaml
conda activate myconda&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;콘다 가상환경을 생성할 때 -f 옵션을 주고 그 뒤에 yaml 파일 경로를 입력하면 해당 파일을 기반으로 가상환경을 만들어준다. 가상환경을 생성할 때 pip 명령어로 설치가 불가능한 패키지들이 있다면(혹은 다른 이유로든 설치가 불가능한 패키지가 있다면) 해당 패키지까지만 설치가 진행되고 가상환경이 생성된다. 따라서 &lt;b&gt;설치를 진행하는 도중 커맨드 창을 잘 확인하고 문제가 되는 패키지들을 적절히 지우거나 주석처리를 해주고 재설치를 해주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;콘다 환경 삭제는 아래의 커맨드로 해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660630382624&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda env remove -n myconda&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #3 : 같은 머신 내에서 콘다 환경 복사&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위의 방법들은 다른 머신에서 콘다 환경을 복사하는 경우에 사용 가능하다. 사실 같은 머신 내에서 콘다 환경을 복사하는 것은 훨씬 간단하다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660630489198&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create -n myconda_copy --clone myconda&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;콘다에선 위와 같이 --clone 옵션을 제공한다. -n 뒤엔 새롭게 복사할 환경의 이름을, --clone 옵션 뒤엔 복사할 대상이 되는 기존 환경의 이름을 써주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;참고 : &lt;a href=&quot;https://jh-bk.tistory.com/35&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jh-bk.tistory.com/35&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>anaconda</category>
      <category>conda env</category>
      <category>아나콘다</category>
      <category>아나콘다 가상환경</category>
      <category>콘다</category>
      <category>콘다 가상환경</category>
      <category>콘다 가상환경 복사</category>
      <category>콘다 가상환경 복제</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/381</guid>
      <comments>https://otugi.tistory.com/381#entry381comment</comments>
      <pubDate>Tue, 16 Aug 2022 15:16:55 +0900</pubDate>
    </item>
    <item>
      <title>리눅스(Linux) 아나콘다(Anaconda) 설치</title>
      <link>https://otugi.tistory.com/380</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아나콘다(Anaconda)는 AI나 데이터 과학 패키지를 많이 포함하고 있다. 아나콘다를 통해 이들을 일괄적으로 편리하게 설치할 수 있다. 이 글에선 리눅스에 아나콘다를 설치하는 방법을 소개한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #1 : 아나콘다 사이트에 접속해 installer 다운로드&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://www.anaconda.com/products/distribution&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.anaconda.com/products/distribution&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660628593532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Anaconda | Anaconda Distribution&quot; data-og-description=&quot;Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine learning on a single machine.&quot; data-og-host=&quot;www.anaconda.com&quot; data-og-source-url=&quot;https://www.anaconda.com/products/distribution&quot; data-og-url=&quot;https://www.anaconda.com/products/distribution&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIV0rT/hyPsLLEYWZ/T2Ken61LATPSL5TRwgI0ek/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/N4kXI/hyPsSYicwU/b8rJhL3jUN9PEB7BUblQnk/img.jpg?width=796&amp;amp;height=418&amp;amp;face=0_0_796_418,https://scrap.kakaocdn.net/dn/SmEdR/hyPsRkNMSZ/ELkDhvAI53x7CM4Ksvrk90/img.png?width=650&amp;amp;height=650&amp;amp;face=0_0_650_650&quot;&gt;&lt;a href=&quot;https://www.anaconda.com/products/distribution&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.anaconda.com/products/distribution&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIV0rT/hyPsLLEYWZ/T2Ken61LATPSL5TRwgI0ek/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/N4kXI/hyPsSYicwU/b8rJhL3jUN9PEB7BUblQnk/img.jpg?width=796&amp;amp;height=418&amp;amp;face=0_0_796_418,https://scrap.kakaocdn.net/dn/SmEdR/hyPsRkNMSZ/ELkDhvAI53x7CM4Ksvrk90/img.png?width=650&amp;amp;height=650&amp;amp;face=0_0_650_650');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Anaconda | Anaconda Distribution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine learning on a single machine.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.anaconda.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 공식 사이트에 접속해서 자신의 OS에 맞는 아나콘다를 설치해주면 된다. 사이트에 접속해서 리눅스 모양을 클릭하면 설치가능한 installer가 있는 곳으로 리다이렉트 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tjZLl/btrJRkmEd1H/vU56OsnsYNljk6vkn8wYkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tjZLl/btrJRkmEd1H/vU56OsnsYNljk6vkn8wYkk/img.png&quot; data-alt=&quot;설치 페이지에서 리눅스 모양을 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tjZLl/btrJRkmEd1H/vU56OsnsYNljk6vkn8wYkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtjZLl%2FbtrJRkmEd1H%2FvU56OsnsYNljk6vkn8wYkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1481&quot; height=&quot;450&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치 페이지에서 리눅스 모양을 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 아래와 같은 페이지로 이동하는데, 여기서 Linux의 installer 중 자신에게 맞는 것을 설치하면 된다. 일반적으로 맨 위의 64-Bit(x86) Installer를 설치하면 된다. 리눅스의 경우 커맨드로 설치가 가능하기 때문에 해당 인스톨러에 커서를 두고 우클릭을 해 링크주소 복사를 하고 wget을 사용해 아래처럼 설치하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660628850098&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #2 : 아나콘다 설치&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이제 위에서 설치한 인스톨러가 다 설치되었으면 해당 sh 파일을 실행시켜 아나콘다 설치가 가능하다. 설치는 아래 커맨드를 입력하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660628948366&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sh Anaconda3-2022.05-Linux-x86_64.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치가 완료되면 기본적으로 (base)라고 하는 콘다 가상환경이 생길텐데 &quot;conda info --envs&quot; 명령어로 자신의 컴퓨터에 존재하는 콘다 가상환경 리스트를 확인할 수 있다. 이 명령어가 제대로 동작한다면 설치가 정상적으로 완료된 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고 :&amp;nbsp;&lt;a href=&quot;https://talkit.tistory.com/640&quot;&gt;https://talkit.tistory.com/640&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>AI</category>
      <category>anaconda</category>
      <category>Anaconda 설치</category>
      <category>linux</category>
      <category>ML</category>
      <category>리눅스</category>
      <category>리눅스 아나콘다 설치</category>
      <category>아나콘다</category>
      <category>아나콘다 설치</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/380</guid>
      <comments>https://otugi.tistory.com/380#entry380comment</comments>
      <pubDate>Tue, 16 Aug 2022 14:54:02 +0900</pubDate>
    </item>
    <item>
      <title>리눅스(Linux) 아나콘다(Anaconda) 설치</title>
      <link>https://otugi.tistory.com/379</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아나콘다(Anaconda)는 AI나 데이터 과학 패키지를 많이 포함하고 있다. 아나콘다를 통해 이들을 일괄적으로 편리하게 설치할 수 있다. 이 글에선 리눅스에 아나콘다를 설치하는 방법을 소개한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #1 : 아나콘다 사이트에 접속해 installer 다운로드&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://www.anaconda.com/products/distribution&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.anaconda.com/products/distribution&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660628593532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Anaconda | Anaconda Distribution&quot; data-og-description=&quot;Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine learning on a single machine.&quot; data-og-host=&quot;www.anaconda.com&quot; data-og-source-url=&quot;https://www.anaconda.com/products/distribution&quot; data-og-url=&quot;https://www.anaconda.com/products/distribution&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIV0rT/hyPsLLEYWZ/T2Ken61LATPSL5TRwgI0ek/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/N4kXI/hyPsSYicwU/b8rJhL3jUN9PEB7BUblQnk/img.jpg?width=796&amp;amp;height=418&amp;amp;face=0_0_796_418,https://scrap.kakaocdn.net/dn/SmEdR/hyPsRkNMSZ/ELkDhvAI53x7CM4Ksvrk90/img.png?width=650&amp;amp;height=650&amp;amp;face=0_0_650_650&quot;&gt;&lt;a href=&quot;https://www.anaconda.com/products/distribution&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.anaconda.com/products/distribution&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIV0rT/hyPsLLEYWZ/T2Ken61LATPSL5TRwgI0ek/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/N4kXI/hyPsSYicwU/b8rJhL3jUN9PEB7BUblQnk/img.jpg?width=796&amp;amp;height=418&amp;amp;face=0_0_796_418,https://scrap.kakaocdn.net/dn/SmEdR/hyPsRkNMSZ/ELkDhvAI53x7CM4Ksvrk90/img.png?width=650&amp;amp;height=650&amp;amp;face=0_0_650_650');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Anaconda | Anaconda Distribution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine learning on a single machine.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.anaconda.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 공식 사이트에 접속해서 자신의 OS에 맞는 아나콘다를 설치해주면 된다. 사이트에 접속해서 리눅스 모양을 클릭하면 설치가능한 installer가 있는 곳으로 리다이렉트 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/urxk5/btrJMAYqTng/08SHIn2MRXhhJzhyIgrJDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/urxk5/btrJMAYqTng/08SHIn2MRXhhJzhyIgrJDK/img.png&quot; data-alt=&quot;설치 페이지에서 리눅스 모양을 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/urxk5/btrJMAYqTng/08SHIn2MRXhhJzhyIgrJDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Furxk5%2FbtrJMAYqTng%2F08SHIn2MRXhhJzhyIgrJDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1481&quot; height=&quot;450&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치 페이지에서 리눅스 모양을 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 아래와 같은 페이지로 이동하는데, 여기서 Linux의 installer 중 자신에게 맞는 것을 설치하면 된다. 일반적으로 맨 위의 64-Bit(x86) Installer를 설치하면 된다. 리눅스의 경우 커맨드로 설치가 가능하기 때문에 해당 인스톨러에 커서를 두고 우클릭을 해 링크주소 복사를 하고 wget을 사용해 아래처럼 설치하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660628850098&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step #2 : 아나콘다 설치&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이제 위에서 설치한 인스톨러가 다 설치되었으면 해당 sh 파일을 실행시켜 아나콘다 설치가 가능하다. 설치는 아래 커맨드를 입력하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660628948366&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sh Anaconda3-2022.05-Linux-x86_64.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치가 완료되면 기본적으로 (base)라고 하는 콘다 가상환경이 생길텐데 &quot;conda info --envs&quot; 명령어로 자신의 컴퓨터에 존재하는 콘다 가상환경 리스트를 확인할 수 있다. 이 명령어가 제대로 동작한다면 설치가 정상적으로 완료된 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고 :&amp;nbsp;&lt;a href=&quot;https://talkit.tistory.com/640&quot;&gt;https://talkit.tistory.com/640&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>AI</category>
      <category>anaconda</category>
      <category>Anaconda 설치</category>
      <category>linux</category>
      <category>ML</category>
      <category>리눅스</category>
      <category>리눅스 아나콘다 설치</category>
      <category>아나콘다</category>
      <category>아나콘다 설치</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/379</guid>
      <comments>https://otugi.tistory.com/379#entry379comment</comments>
      <pubDate>Tue, 16 Aug 2022 14:53:07 +0900</pubDate>
    </item>
    <item>
      <title>WSL과 WSL2 설치 및 VScode 연동(윈도우에서 리눅스 사용하기)</title>
      <link>https://otugi.tistory.com/378</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;윈도우에서 개발을 하다보면 불편한 점이 한 두가지가 아니다. &lt;s&gt;(일단 ls 대신 dir 칠때부터 깊은 빡침이...)&lt;/s&gt; 윈도에서도 리눅스 환경을 사용할 수 있는 방법이 있다. WSL을 업데이트한 WSL2가 나오면서 이젠 많이 편해졌다고 한다. WSL이란 Windows Subsystem for Linux의 줄임말로 윈도우에서 리눅스 환경을 사용할 수 있도록 해주는 도구이다.(리눅스에서 사용하던 커맨드들 그대로 사용가능하다!!!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step1 : WSL 설치하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;윈도우 우측하단에 검색창에 &quot;windows 기능&quot;이라고 치고 들어가면 아래와 같은 창이 뜬다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mnf1T/btrHIZFAa6T/BbLDKLPT1a0vmEXQl78kd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mnf1T/btrHIZFAa6T/BbLDKLPT1a0vmEXQl78kd0/img.png&quot; data-alt=&quot;windows 기능 켜기/끄기 창&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mnf1T/btrHIZFAa6T/BbLDKLPT1a0vmEXQl78kd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmnf1T%2FbtrHIZFAa6T%2FBbLDKLPT1a0vmEXQl78kd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;483&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;windows 기능 켜기/끄기 창&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 &lt;b&gt;Linux용 Windows 하위 시스템&lt;/b&gt;의 체크박스에 체크를 해주면 된다. 필요한 파일들의 설치가 진행되고 재부팅이 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step 2 : Ubuntu 설치하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음으로 Microsoft Store에 들어가서 Linux라고 검색한 뒤 Ubuntu를 설치해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RVtFz/btrHIlPLjFx/y2MQJYIyk4Kk00kQoi3HbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RVtFz/btrHIlPLjFx/y2MQJYIyk4Kk00kQoi3HbK/img.png&quot; data-alt=&quot;Microsoft Store에서 우분투 설치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RVtFz/btrHIlPLjFx/y2MQJYIyk4Kk00kQoi3HbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRVtFz%2FbtrHIlPLjFx%2Fy2MQJYIyk4Kk00kQoi3HbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1272&quot; height=&quot;850&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Microsoft Store에서 우분투 설치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나의 경우 Ubuntu 20.04.4 LTS를 설치해주었다. 설치가 완료되고 실행하면 검은 프롬프트 창이 뜨면서 필요한 파일들이 설치된다. 다 설치가 되면 계정을 입력하라는 문구가 나온다. 이 계정은 리눅스에서 사용하는 것처럼 user 계정이니 윈도우와는 별개의 것이다. 본인이 편한 이름으로 만들면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step 3 : WSL2 설치하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;WSL2는 먼저 WSL 설치가 완료된 뒤 업데이트 하는 방식으로 설치가 가능하다. Step1에서와 같이 Windows 기능 켜기/끄기 창에 들어가 &lt;b&gt;가상 머신 플랫폼&lt;/b&gt;에 체크해주면 된다. 필요한 파일들이 설치된 후 재부팅이 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GwG8S/btrHK0XBcrM/kDKKjYhybM2kkvbgUgtqFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GwG8S/btrHK0XBcrM/kDKKjYhybM2kkvbgUgtqFk/img.png&quot; data-alt=&quot;가상 머신 플랫폼 체크 박스 체크해주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GwG8S/btrHK0XBcrM/kDKKjYhybM2kkvbgUgtqFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGwG8S%2FbtrHK0XBcrM%2FkDKKjYhybM2kkvbgUgtqFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;483&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;가상 머신 플랫폼 체크 박스 체크해주기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi&quot;&gt;x64 머신용 최신 WSL2 Linux 커널 업데이트 패키지&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 위 링크를 통해 리눅스 커널 업데이트 패키지를 설치해준다. 설치가 완료되면 Windows Powershell을 관리자 권한으로 열어 &lt;b&gt;wsl -l -v&lt;/b&gt;를 입력해 버전을 확인해준다. 업그레이드를 진행하지 않았으면 version이 1로 뜰 것이다. 이를 위해 아래의 두 명령어를 차례로 입력해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658235066322&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --set-default-version 2
wsl --set-version &amp;lt;wsl이름&amp;gt; 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;lt;wsl이름&amp;gt;에는 자신이 원하는 WSL 환경의 이름을 넣어주면 된다. 나의 경우 Ubuntu-20.04.4로 입력하였다. 차례로 입력 후 몇 분 기다리면 WSL2로 업데이트가 완료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step 4 : VScode 연동하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;VScode에서 바로 WSL을 사용하려면 &lt;b&gt;Remote - WSL&lt;/b&gt; 이라고 하는 Extension을 설치해주어야 한다. 설치가 완료되면 VScode 창에서 좌측 하단에 아래 사진처럼 초록색의 &amp;gt;&amp;lt; 모양처럼 생긴 원격 연결 버튼이 생긴다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LGUrH/btrHJa7XCpq/KQSCCQUHRJKEaRQH0IxJP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LGUrH/btrHJa7XCpq/KQSCCQUHRJKEaRQH0IxJP1/img.png&quot; data-alt=&quot;VScode 원격 연결 버튼&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LGUrH/btrHJa7XCpq/KQSCCQUHRJKEaRQH0IxJP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLGUrH%2FbtrHJa7XCpq%2FKQSCCQUHRJKEaRQH0IxJP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;393&quot; height=&quot;187&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;VScode 원격 연결 버튼&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이거를 클릭한 뒤 &lt;b&gt;New WSL Window&lt;/b&gt;를 눌러 새 WSL 창을 열 수도 있고, &lt;b&gt;Open Folder in WSL&lt;/b&gt;을 눌러 원하는 프로젝트 폴더를 WSL 환경으로 열어 작업할 수도 있다. 참고로 WSL 환경으로 창을 열면 윈도우 환경의 본인 PC에 리눅스 환경을 위한 새로운 폴더가 아예 따로 생긴다. 다시 말해, WSL 환경은 원격 컴퓨터처럼 접속이 되는거라 모든 익스텐션이나 패키지 설치 등 환경 세팅을 기존의 윈도우 컴퓨터와 별개로 다시 해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;연결을 해제하려면 다시 좌측 하단의 원격 연결 버튼을 누른 뒤 &lt;b&gt;원격 연결 닫기&lt;/b&gt;를 눌러주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Reference&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- &lt;a href=&quot;https://velog.io/@gidskql6671/WSL-WSL2-%EC%84%A4%EC%B9%98-VSCode-%EC%97%B0%EB%8F%99&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@gidskql6671/WSL-WSL2-%EC%84%A4%EC%B9%98-VSCode-%EC%97%B0%EB%8F%99&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>리눅스</category>
      <category>linux</category>
      <category>unbuntu</category>
      <category>window</category>
      <category>wsl</category>
      <category>wsl 설치</category>
      <category>WSL2</category>
      <category>리눅스</category>
      <category>우분투</category>
      <category>윈도우에서 리눅스</category>
      <category>윈도우에서 우분투</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/378</guid>
      <comments>https://otugi.tistory.com/378#entry378comment</comments>
      <pubDate>Tue, 19 Jul 2022 22:01:21 +0900</pubDate>
    </item>
    <item>
      <title>RuntimeError: CUDA error: CUBLAS_STATUS_INVALID_VALUE when calling `cublasSgemm 에러 해결</title>
      <link>https://otugi.tistory.com/377</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Error 발생 상황&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;모델 학습을 돌리다보면 다음과 같은 에러를 종종 만나게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1657344266509&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;device-side assert triggered&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1657344334696&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Assertion `srcIndex &amp;lt; srcSelectDimSize` failed.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1657344148121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RuntimeError: CUDA error: CUBLAS_STATUS_INVALID_VALUE when calling `cublasSgemm( handle, opa, opb, m, n, k, &amp;amp;alpha, a, lda, b, ldb, &amp;amp;beta, c, ldc)`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Error의 원인&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GPU단에서의 에러 메시지는 이처럼 자세한 이유를 드러나지 않아 디버깅이 쉽지 않다. &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;위와 같은 에러의 원인은 대게 차원(dimension)이 일치하지 않아 발생하는 문제&lt;/span&gt;&lt;/b&gt;이다. 즉, input으로 모델에 주입하는 데이터의 차원과 모델의 차원이 일치하지 않는 경우이다. 예컨대, input 데이터의 차원은 1025인데 model의 차원이 1024인 경우 위와 같은 에러가 발생한다. 비슷한 예시로는 classification을 할 때에 데이터의 클래스가 모델의 마지막 layer에서 정해둔 차원수(클래스 갯수)와 일치하지 않는 경우도 위 에러가 발생할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나의 경우&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Device side의 에러는 워낙 원인이 다양한지라...내가 직접 실험을 돌리며 해결한 사례를 아래에 예시로 설명하고자 한다. 나의 경우 huggingface의 transformers를 사용해 distilbart 모델로 text generation을 하는 task를 학습 중이었다. 그런데 위와 같은 에러가 발생하였고, 분석해보니 모델의 차원 수보다 더 큰 차원의 text를 생성하도록 한 것이 원인이었다는 사실을 알게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래는 내가 사용한 모델의 config.json 파일 내용이다. 모델에서 사용하는 변수들에 대한 정보가 담겨져 있다. 모델의 이름은 sshleifer/distilbart-xsum-9-6이었고 &lt;b&gt;d_model&lt;/b&gt;=1024로 해당 모델의 차원이 1024라는 것을 알 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TQ26U/btrGQwjRr5m/6JAu7L3jituW8VD3GrHM51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TQ26U/btrGQwjRr5m/6JAu7L3jituW8VD3GrHM51/img.png&quot; data-alt=&quot;model config 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TQ26U/btrGQwjRr5m/6JAu7L3jituW8VD3GrHM51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTQ26U%2FbtrGQwjRr5m%2F6JAu7L3jituW8VD3GrHM51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;506&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;model config 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;모델을 직접 다운받아 사용하지 않는 경우라면 아래와 같이&amp;nbsp;&lt;a href=&quot;https://huggingface.co/docs/transformers/model_doc/bart#transformers.BartConfig&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;허깅페이스 사이트&lt;/a&gt;에서 해당 모델의 default configuration을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IZqWR/btrGQEWTUAh/xNCq324BbStqLLQ3M6mBs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IZqWR/btrGQEWTUAh/xNCq324BbStqLLQ3M6mBs0/img.png&quot; data-alt=&quot;huggingface model configuration&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IZqWR/btrGQEWTUAh/xNCq324BbStqLLQ3M6mBs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIZqWR%2FbtrGQEWTUAh%2FxNCq324BbStqLLQ3M6mBs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1161&quot; height=&quot;726&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;huggingface model configuration&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나의 경우는 text를 generation하는 task를 학습시키고 있었고 내 용도에 따라 모델의 최소, 최대 생성길이를 별도로 설정해주었다. 별문제가 없을 거라고 치부해 그냥 충분히 긴 텍스트를 생성하도록 model.config.max_length=2000으로 설정해주었는데 이는 모델의 최대 텍스트 생성 길이를 2000으로 한다는 것이다.(&lt;s&gt;설마 2000이나 되는 길이의 텍스트를 생성할 일이 있겠어....하면서 말이다...&lt;/s&gt;) 일부 데이터 샘플 중 길이 1024 이상으로 text generation이 되는 것들이 있었고 이에 따라 학습 도중 위와 같은 에러가 나면서 학습이 중단되었다.따라서, model config값에서 &lt;b&gt;model.config.max_length&lt;/b&gt;의 값을 모델의 차원과 같은 1024로 해주었더니 에러를 해결할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;결론은 위와 같은 에러를 만나면 우선 모델의 layer들의 차원과 데이터의 차원 간에 불일치하는 곳이 없는지 살펴보는 것이 중요하다. &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;중간 층(intermediate layer)에서 문제가 발생하는 경우는 거의 없는 것 같고, 대부분 처음 layer(data가 주입되는 layer)나 마지막 layer를 살펴보면 된다. 처음 layer에서 문제인 경우 데이터의 차원 수와 모델의 차원 수가 맞지 않아서인 경우가 많고, 마지막 layer에서 문제인 경우는 대게 자신이 설정한 모델의 output 값(결국 마지막 layer의 차원 수가 되는 값)이 feeding해주는 데이터와 일치하지 않아서인 경우가 많다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>cublasSgemm</category>
      <category>CUBLAS_STATUS_INVALID_VALUE</category>
      <category>CUDA runtime error</category>
      <category>devic</category>
      <category>device-side assert triggered</category>
      <category>GPU에러</category>
      <category>huggingface</category>
      <category>model config</category>
      <category>트랜스포머</category>
      <category>허깅페이스</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/377</guid>
      <comments>https://otugi.tistory.com/377#entry377comment</comments>
      <pubDate>Sat, 9 Jul 2022 14:41:06 +0900</pubDate>
    </item>
    <item>
      <title>GPU 최적화, GPU 사용률 늘리는 방법</title>
      <link>https://otugi.tistory.com/376</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;GPU를 사용해 모델 학습을 돌리다보면 GPU의 사용률이 저조하게 나오는 경우가 있다. 이런 경우 충분한 자원이 있더라도 학습에 오랜 시간이 걸리게 된다. 이 때 필요한 것이 GPU 사용률을 최적화시키는 것이다. 방법은 많지만 그 중 가장 대표적인 방법을 소개하고자 한다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;GPU 사용률이 저조한 이유는 대부분 CPU단에서 데이터 처리가 GPU에서의 처리 속도를 따라가지 못해 발생한다.&lt;/span&gt; 즉, GPU에서 처리할 데이터가 CPU에서 아직 프로세싱을 거쳐서 준비가 다 되지 않은 경우이다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;num_workers 설정해주기&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;pytorch와 huggingface의 transformers엔 모두 num_workers라는 파라미터를 설정해줄 수 있다. 이는 학습 도중 CPU의 작업에 몇 개의 코어를 사용할지를 결정하는 변수이다. huggingface의 transformers에선 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;dataloader_num_workers&lt;/span&gt; 파라미터값을 설정해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot; data-token-index=&quot;0&quot; data-reactroot=&quot;&quot;&gt;아래 코드는 transformers 패키지를 사용해 training arguments와 trainer를 선언하는 부분이다. 여기서 args에 dataloader_num_workers=4라고 넘겨주었는데 이는 코어 4개를 사용해 CPU 작업을 처리하겠다는 뜻이다. 이처럼 num_workers를 늘려줌으로 GPU가 처리하는 속도에 조금 더 맞추어 빠르게 CPU에서 데이터를 준비할 수 있어 GPU 사용률을 늘릴 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1656821618853&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;args = Seq2SeqTrainingArguments(
    output_dir = &quot;saved_model&quot;,
    overwrite_output_dir = True,
    evaluation_strategy = &quot;epoch&quot;,
    save_strategy = &quot;epoch&quot;,
    learning_rate=2e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    gradient_accumulation_steps=2,
    weight_decay=0.01,
    num_train_epochs=epochs,
    predict_with_generate=True,
    fp16=False,
    dataloader_num_workers=4
)
trainer = Seq2SeqTrainer(
    model,
    args,
    train_dataset=tokenized_datasets[&quot;train&quot;],
    eval_dataset=tokenized_datasets[&quot;validation&quot;],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Reference&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- &lt;a href=&quot;https://chaelin0722.github.io/etc/gpu_utility/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://chaelin0722.github.io/etc/gpu_utility/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- &lt;a href=&quot;https://huggingface.co/docs/transformers/main_classes/trainer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://huggingface.co/docs/transformers/main_classes/trainer&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>dataloader num workers</category>
      <category>GPU optimization</category>
      <category>GPU usage</category>
      <category>GPU 사용률</category>
      <category>GPU 최적화</category>
      <category>huggingface</category>
      <category>num workers</category>
      <category>pytorch</category>
      <category>배치 처리</category>
      <category>학습 최적화</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/376</guid>
      <comments>https://otugi.tistory.com/376#entry376comment</comments>
      <pubDate>Sun, 3 Jul 2022 13:17:43 +0900</pubDate>
    </item>
    <item>
      <title>1초 단위로 GPU 사용량과 메모리 확인하기(GPU 모니터링)</title>
      <link>https://otugi.tistory.com/375</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모델 학습을 돌리다보면 GPU 상태를 모니터링해야 되는 경우가 종종 있다. 내가 지정한 GPU로 프로그램이 잘 돌아가고 있는지, GPU 메모리가 학습이 진행되는 정도에 따라 얼만큼 점유되고 있는지, GPU 사용률이 충분히 높게 잡히고 있는지 같은 사항들을 확인해야 되는 경우들이 그러하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이럴 땐 아래의 커맨드로 확인이 가능하다. 리눅스 커맨드 창에 아래와 같은 명령어를 입력하면 1초 단위로 갱신되는 GPU 상태를 모니터링할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1656417154987&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;watch -n -1 nvidia-smi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WqvSs/btrFZKW1SJZ/3rEUGlgVqtsqgqQwnwzgBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WqvSs/btrFZKW1SJZ/3rEUGlgVqtsqgqQwnwzgBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WqvSs/btrFZKW1SJZ/3rEUGlgVqtsqgqQwnwzgBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWqvSs%2FbtrFZKW1SJZ%2F3rEUGlgVqtsqgqQwnwzgBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;480&quot; height=&quot;365&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>cuda</category>
      <category>gpu</category>
      <category>GPU 메모리</category>
      <category>GPU 모니터링</category>
      <category>GPU 사용률</category>
      <category>model training</category>
      <category>nvidia-smi</category>
      <category>딥러닝</category>
      <category>모델 학습</category>
      <category>트레이닝</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/375</guid>
      <comments>https://otugi.tistory.com/375#entry375comment</comments>
      <pubDate>Tue, 28 Jun 2022 20:54:20 +0900</pubDate>
    </item>
    <item>
      <title>허깅페이스(Huggingface) 모델 inference(pipeline) GPU로 돌리기</title>
      <link>https://otugi.tistory.com/374</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;허깅페이스를 사용하다보면 이미 만들어진 모델을 불러와서 inference만 하고자 하는 때가 있다. 가령 이미 학습된 NER 모델을 불러와 데이터 처리를 한다거나, Summarization 모델을 불러와서 필요한 문서에 대한 summarization을 수행하려고 하는 경우가 그러하다. 보통 이런 때엔 허깅페이스의 pipeline 기능을 사용한다. 그런데 처리하고자 하는 데이터가 대용량인 경우 시간이 오래 걸리는 경우가 많다. 이런 때 &lt;b&gt;GPU를 사용해 model infernece를 돌리는 방법&lt;/b&gt;에 대해 소개한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고로 이 방법은 실험을 하면서 내가 필요했던 기능인데 구글 검색을 통해 찾아봐도 나오지 않아서 ...ㅜㅜ 혼자 공식문서를 읽어서 파악하고 직접 실험을 돌리며 알아낸 것이다....!&lt;/p&gt;
&lt;pre id=&quot;code_1656250085090&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from transformers import AutoTokenizer, AutoModelForTokenClassification, pipeline

tokenizer = AutoTokenizer.from_pretrained(&quot;dslim/bert-large-NER&quot;)
model = AutoModelForTokenClassification.from_pretrained(&quot;dslim/bert-large-NER&quot;)
ner = pipeline(&quot;ner&quot;, model=model, tokenizer=tokenizer, device=1)
print(ner(large_data))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 예시는 &quot;dslim/bert-large-NER&quot;이라는 NER task에 pre-train된 bert-large모델을 사용해 large_text라는 데이터에 NER을 수행하는 코드이다. 자신이 처리하려는 task에 따라 적절히 모델이름을 바꾸거나 task 이름을 바꾸면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 pipeline에 device 파라미터를 설정해주면 된다. 공식문서에 따르면 기본값은 -1로 설정되어있는데 이는 CPU를 사용해 model inference(모델 추론)을 돌린다는 것이다. 이를 사용하고자 하는 GPU의 넘버로 값을 바꾸어 전달해주면 해당 GPU를 사용해 추론을 돌릴 수 있다!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>GPU inference</category>
      <category>GPU 추론</category>
      <category>huggingface</category>
      <category>model inference</category>
      <category>pipeline</category>
      <category>TRANSFORMER</category>
      <category>Transformers</category>
      <category>모델 추론</category>
      <category>파이프라인</category>
      <category>허깅페이스</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/374</guid>
      <comments>https://otugi.tistory.com/374#entry374comment</comments>
      <pubDate>Sun, 26 Jun 2022 22:30:59 +0900</pubDate>
    </item>
    <item>
      <title>NLP 분야 Data augmentation</title>
      <link>https://otugi.tistory.com/372</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;요즘 내가 연구하고 있는 분야가 NLP에서 low resource환경에서 사용할 수 있는 data augmentation이다. NLP 분야에서 사용되는 data augmentation은 vision 분야와 약간 다른 특성을 갖는다. 이에 대해 종합적으로 잘 정리해둔 블로그가 있어 링크를 달아둔다. 문맥적인 변화를 주는 것인지, 외형적인 변화를 주는 것인지와 같은 큰 틀에 따라 방법을 나누고 그 안에서 다시 세부적인 방법론에 따라 내용을 나누어 설명한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://amitness.com/2020/05/data-augmentation-for-nlp/?fbclid=IwAR11MkccCti-2cD93RYftNPHb7Wxdj7AlZG7NNG4EhPaBkmiJkcBPtdl1eo&quot;&gt;https://amitness.com/2020/05/data-augmentation-for-nlp/?fbclid=IwAR11MkccCti-2cD93RYftNPHb7Wxdj7AlZG7NNG4EhPaBkmiJkcBPtdl1eo&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1653711870552&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;A Visual Survey of Data Augmentation in NLP&quot; data-og-description=&quot;An extensive overview of text data augmentation techniques for Natural Language Processing&quot; data-og-host=&quot;amitness.com&quot; data-og-source-url=&quot;https://amitness.com/2020/05/data-augmentation-for-nlp/?fbclid=IwAR11MkccCti-2cD93RYftNPHb7Wxdj7AlZG7NNG4EhPaBkmiJkcBPtdl1eo&quot; data-og-url=&quot;https://amitness.com/2020/05/data-augmentation-for-nlp/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bntnKm/hyOzUWfmDu/G38ATk2clYWzNrnuYXVkF0/img.png?width=534&amp;amp;height=255&amp;amp;face=0_0_534_255,https://scrap.kakaocdn.net/dn/MUYN0/hyOzLrs73o/UKgoD1DR7jbouiXmSkXqrk/img.png?width=534&amp;amp;height=255&amp;amp;face=0_0_534_255,https://scrap.kakaocdn.net/dn/eyw8Cb/hyOzSRFJOp/4Gkl87m4LLkK9uNF8qjKm1/img.png?width=592&amp;amp;height=276&amp;amp;face=0_0_592_276&quot;&gt;&lt;a href=&quot;https://amitness.com/2020/05/data-augmentation-for-nlp/?fbclid=IwAR11MkccCti-2cD93RYftNPHb7Wxdj7AlZG7NNG4EhPaBkmiJkcBPtdl1eo&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://amitness.com/2020/05/data-augmentation-for-nlp/?fbclid=IwAR11MkccCti-2cD93RYftNPHb7Wxdj7AlZG7NNG4EhPaBkmiJkcBPtdl1eo&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bntnKm/hyOzUWfmDu/G38ATk2clYWzNrnuYXVkF0/img.png?width=534&amp;amp;height=255&amp;amp;face=0_0_534_255,https://scrap.kakaocdn.net/dn/MUYN0/hyOzLrs73o/UKgoD1DR7jbouiXmSkXqrk/img.png?width=534&amp;amp;height=255&amp;amp;face=0_0_534_255,https://scrap.kakaocdn.net/dn/eyw8Cb/hyOzSRFJOp/4Gkl87m4LLkK9uNF8qjKm1/img.png?width=592&amp;amp;height=276&amp;amp;face=0_0_592_276');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;A Visual Survey of Data Augmentation in NLP&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An extensive overview of text data augmentation techniques for Natural Language Processing&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;amitness.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>NLP</category>
      <category>data augmentation</category>
      <category>nlp</category>
      <category>데이터 증식</category>
      <category>자연어처리</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/372</guid>
      <comments>https://otugi.tistory.com/372#entry372comment</comments>
      <pubDate>Sat, 28 May 2022 13:26:06 +0900</pubDate>
    </item>
    <item>
      <title>Shell 스크립트 내에서 반복문 사용</title>
      <link>https://otugi.tistory.com/371</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;쉘 스크립트에서 반복문을 사용하면 일일히 입력하지 않고도 편하게 실행시킬 수 있다. 단순히 반복문을 필요로 하는 구현(예컨대, 구구단 같은)뿐 아니라 특정 실행 파일에 다양한 인자를 input으로 주어 실행하는 것도 자동화시킬 수가 있다. 그렇다면 shell 스크립트(sh 파일)를 작성하는데 내부에서 반복문을 사용하려면 어떻게 해야 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기본 반복&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래와 같이 in 다음에 띄어쓰기 구분된 숫자의 리스트를 넣어주면 해당 숫자들을 돌면서 순회한다.&lt;/p&gt;
&lt;pre id=&quot;code_1652598473515&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for num in 1 2 3 4 5
do
    echo &quot;The num is ${num}&quot;
done
# 출력결과
# The num is 1
# The num is 2
# The num is 3
# The num is 4
# The num is 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 주의할 점은 아래와 같이 &quot;&quot;로 묶어서 in 다음에 넣어주면 해당 따옴표로 묶인 전체를 문자열로 인식해서 출력한다는 점이다.&lt;/p&gt;
&lt;pre id=&quot;code_1652598594228&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for num in &quot;1 2 3 4 5&quot;
do
    echo &quot;The num is ${num}&quot;
done
# 출력 결과
# The num is 1 2 3 4 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;리스트로 만들어 반복&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1652598330526&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;list=&quot;1 2 3 4 5&quot;
for num in ${list}
do
    echo &quot;The num is ${num}&quot;
done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 코드를 실행시키면 아래와 같은 결과가 나온다.&lt;/p&gt;
&lt;pre id=&quot;code_1652598384163&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;The num is 1
The num is 2
The num is 3
The num is 4
The num is 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>리눅스</category>
      <category>shell</category>
      <category>shell for</category>
      <category>shell programming</category>
      <category>shell script</category>
      <category>쉘</category>
      <category>쉘 반복문</category>
      <category>쉘 스크립트</category>
      <category>쉘 스크립트 반복문</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/371</guid>
      <comments>https://otugi.tistory.com/371#entry371comment</comments>
      <pubDate>Sun, 15 May 2022 16:10:51 +0900</pubDate>
    </item>
    <item>
      <title>텍스트를 문장 단위로 분할하기(nltk, sentence tokenizing)</title>
      <link>https://otugi.tistory.com/370</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&quot;Hello, David. I made some cookies. Do you want som?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같은 영어 텍스트를 문장 단위로 분할하려면 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자연어 처리 toolkit인 NLTK에 바로 이러한 기능이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 커맨드 창에 아래의 명령어를 입력하여 nltk를 설치해주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1652597762081&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install nltk
python -m nltk.downloader all&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1652597556202&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from nltk import sent_tokenize

text = &quot;Hello, David. I made some cookies. Do you want som?&quot;
tokenized_text = sent_tokenize(text)
print(tokenized_text)

# ['Hello, David.', 'I made some cookies.', 'Do you want som?']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;nltk의 sent_tokenize 메소드는 위와 같이 파라미터로 주어진 텍스트에 대해 문장 단위로 끊어 리스트로 반환해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>nlp</category>
      <category>nltk</category>
      <category>sentence tokenize</category>
      <category>sentence tokenizing</category>
      <category>tokenize</category>
      <category>tokenizing</category>
      <category>문장 분리</category>
      <category>자연어 처리</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/370</guid>
      <comments>https://otugi.tistory.com/370#entry370comment</comments>
      <pubDate>Sun, 15 May 2022 15:56:55 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2022 구글 킥스타트 Round B Palindromic Factors 풀이</title>
      <link>https://otugi.tistory.com/366</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1650779852861&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bl0wy5/hyN9J9a7Qv/PsCJEBgGSBKTm4NbkGPDV1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bl0wy5/hyN9J9a7Qv/PsCJEBgGSBKTm4NbkGPDV1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 약수를 구하는 함수 findFactors()를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 팰린드롬인지를 판별하는 isPalindrome() 함수를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;약수를 구하기 위해선 1~int(sqrt(A))+1 만큼의 범위 동안 나누어 떨어지는 수를 찾으면 된다. 중복되는 경우가 생길 수 있으니 set에 저장한다.(예컨대, 25의 경우 5*5이므로 5가 중복으로 카운트 된다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;팰린드롬을 판별하기 위해선 길이가 짝수, 홀수인 경우로 나누어 주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1650779972379&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/00000000008caa74/0000000000acee89
import math 

def findFactors(a):
    factor_set = set()
    for i in range(1, int(math.sqrt(a))+1):
        if a % i == 0:
            factor_set.add(i)
            factor_set.add(a//i)
    return factor_set

def isPalindrome(s):
    if len(s)==1:
        return True
    if len(s) % 2 == 0:
        left = s[:len(s)//2]
        right = s[len(s)//2:]
    elif len(s) % 2 == 1:
        left = s[:len(s)//2]
        right = s[len(s)//2+1:]
    if left == right[::-1]:
        return True
    return False

for i in range(int(input())):
    n = int(input())
    factors = findFactors(n)
    cnt = 0
    for f in factors:
        if isPalindrome(str(f)):
            cnt += 1
    print(f&quot;Case #{i+1}: &quot; + str(cnt))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>google coding competition</category>
      <category>google kickstart</category>
      <category>kick start</category>
      <category>kickstart 2022</category>
      <category>palindromic factors</category>
      <category>PYTHON</category>
      <category>구글 코딩테스트</category>
      <category>구글 킥스타트</category>
      <category>킥스타트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/366</guid>
      <comments>https://otugi.tistory.com/366#entry366comment</comments>
      <pubDate>Sun, 24 Apr 2022 14:59:30 +0900</pubDate>
    </item>
    <item>
      <title>[백준 12851] 숨바꼭질 2</title>
      <link>https://otugi.tistory.com/363</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12851&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/12851&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1650090217713&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;12851번: 숨바꼭질 2&quot; data-og-description=&quot;수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 &amp;le; N &amp;le; 100,000)에 있고, 동생은 점 K(0 &amp;le; K &amp;le; 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/12851&quot; data-og-url=&quot;https://www.acmicpc.net/problem/12851&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/prcui/hyN2KIHgsa/7y5qNE3gelh2CKKesMt07K/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12851&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/12851&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/prcui/hyN2KIHgsa/7y5qNE3gelh2CKKesMt07K/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;12851번: 숨바꼭질 2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 &amp;le; N &amp;le; 100,000)에 있고, 동생은 점 K(0 &amp;le; K &amp;le; 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;BFS를 사용하여 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;걸린 시간 외에도 경우의 수를 카운트해야 하므로 방문 체크를 일반적인 방식으로 하면 안된다. 일반적인 경우처럼 방문한 곳은 다시 가지 않도록 하면 K까지의 경우의 수는 언제나 1이 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;따라서 visit 체크를 2가지 경우로 나누어주어야 한다.(아래 코드 참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1650090240706&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/12851

from collections import deque

N, K = map(int, input().split())
visit = [[-1,0] for _ in range(100001)] #[걸린시간, 경우의 수]
q = deque()
q.append(N)   #(pos, time)
visit[N][0] = 0
visit[N][1] = 1
while q:
    x = q.popleft()
    for nx in [x-1, x+1, 2*x]:
        if 0&amp;lt;= nx &amp;lt;= 100000:
            # 첫방문이라면
            if visit[nx][0] == -1:
                visit[nx][0] = visit[x][0] + 1
                visit[nx][1] = visit[x][1]
                q.append(nx)
            # 첫방문은 아니지만 최소시간이라면
            elif visit[nx][0] == visit[x][0] + 1:
                visit[nx][1] += visit[x][1]

print(visit[K][0])
print(visit[K][1])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>BFS</category>
      <category>PYTHON</category>
      <category>그래프 탐색</category>
      <category>너비우선탐색</category>
      <category>백준</category>
      <category>백준 12851</category>
      <category>백준 숨바꼭질</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/363</guid>
      <comments>https://otugi.tistory.com/363#entry363comment</comments>
      <pubDate>Sat, 16 Apr 2022 15:25:21 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2638] 치즈</title>
      <link>https://otugi.tistory.com/362</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2638&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2638&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1650085689949&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2638번: 치즈&quot; data-og-description=&quot;첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 &amp;le; N, M &amp;le; 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2638&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2638&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nTtty/hyN2GfbXnr/jHIEQU4mDM8DYEZrkLA3nk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/VRjdM/hyN2L8ESRS/O5dYZtTvNmeBbebsRFrGs0/img.jpg?width=416&amp;amp;height=342&amp;amp;face=0_0_416_342,https://scrap.kakaocdn.net/dn/yncG5/hyN38A9v1a/juIc88IokU0YT9mu4raRD0/img.jpg?width=416&amp;amp;height=342&amp;amp;face=0_0_416_342&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2638&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2638&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nTtty/hyN2GfbXnr/jHIEQU4mDM8DYEZrkLA3nk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/VRjdM/hyN2L8ESRS/O5dYZtTvNmeBbebsRFrGs0/img.jpg?width=416&amp;amp;height=342&amp;amp;face=0_0_416_342,https://scrap.kakaocdn.net/dn/yncG5/hyN38A9v1a/juIc88IokU0YT9mu4raRD0/img.jpg?width=416&amp;amp;height=342&amp;amp;face=0_0_416_342');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2638번: 치즈&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 &amp;le; N, M &amp;le; 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;bfs를 사용하여 풀면 된다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;1. bfs를 (0,0)에서부터 시작한다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;2. 도중에 공기칸을 만나면 큐에 넣어주고, 치즈칸을 만나면 1을 더해준다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;3. 한 번의 bfs를 돌고나서 값이 3 이상인 칸은 2면 이상이 공기와 접하는 것이므로 이 칸의 치즈를 0으로 만든다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;4. 1~3을 모든 치즈가 녹을때까지 반복&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1624349391295&quot; class=&quot;python&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; cursor: default; z-index: 1;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#https://www.acmicpc.net/problem/2638
import sys
input = sys.stdin.readline
from collections import deque

N, M = map(int, input().split())
arr = []
for _ in range(N):
    arr.append(list(map(int, input().strip().split())))
time = 0

def bfs():
    q = deque()
    q.append((0,0))
    visit = set()
    visit.add((0,0))
    while q:
        x, y = q.popleft()
        for dx, dy in ((1,0),(-1,0),(0,1),(0,-1)):
            nx, ny = x + dx, y + dy
            if 0&amp;lt;=nx&amp;lt;N and 0&amp;lt;=ny&amp;lt;M and (nx,ny) not in visit:
                if arr[nx][ny] == 0:
                    q.append((nx,ny))
                    visit.add((nx,ny))
                else:
                    arr[nx][ny] += 1
    for i in range(N):
        for j in range(M):
            if arr[i][j] &amp;gt;= 3:
                arr[i][j] = 0
            elif arr[i][j] == 2:
                arr[i][j] = 1

while True:
    # terminate condition
    total = 0
    for i in range(N):
        total += sum(arr[i])
    if total == 0:
        print(time)
        break

    bfs()
    time += 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>BFS</category>
      <category>PYTHON</category>
      <category>그래프</category>
      <category>너비우선탐색</category>
      <category>백준</category>
      <category>백준 2638</category>
      <category>알고리즘</category>
      <category>치즈</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/362</guid>
      <comments>https://otugi.tistory.com/362#entry362comment</comments>
      <pubDate>Sat, 16 Apr 2022 14:10:46 +0900</pubDate>
    </item>
    <item>
      <title>[백준 11660] 구간 합 구하기 5</title>
      <link>https://otugi.tistory.com/361</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11660&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11660&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1649946337681&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;11660번: 구간 합 구하기 5&quot; data-og-description=&quot;첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 &amp;le; N &amp;le; 1024, 1 &amp;le; M &amp;le; 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/11660&quot; data-og-url=&quot;https://www.acmicpc.net/problem/11660&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ckrmMU/hyN2HjFCBT/dCkcdD5FSgie5yhZCDFTc1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11660&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/11660&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ckrmMU/hyN2HjFCBT/dCkcdD5FSgie5yhZCDFTc1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;11660번: 구간 합 구하기 5&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 &amp;le; N &amp;le; 1024, 1 &amp;le; M &amp;le; 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO4zgU/btrzqAfvVWk/PtgkKDP2i9MhLW7IvLnyhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO4zgU/btrzqAfvVWk/PtgkKDP2i9MhLW7IvLnyhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO4zgU/btrzqAfvVWk/PtgkKDP2i9MhLW7IvLnyhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO4zgU%2FbtrzqAfvVWk%2FPtgkKDP2i9MhLW7IvLnyhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;997&quot; height=&quot;241&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;dp를 사용하면 된다.&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;dp 2차원 리스트에 각 위치에는 (0,0)부터의 부분합을 저장한다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;주황색 부분의 부분합을 구하려면 전체 합에서 A, B, C 부분을 빼주면 된다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;식으로 나타내면,&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;(x2,y2)까지의 부분합 - (A+B) - (A+C) + A 가 된다.&lt;/ol&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;A부분이 두번 빼지니까 마지막에 한 번 더 더해주면 된다.&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1649946760090&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/11660
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
dp = [[0]*(N+1)]
for _ in range(N):
    dp.append([0] + list(map(int, input().strip().split())))
target = []
for _ in range(M):
    x1, y1, x2, y2 = map(int, input().split())
    target.append([x1, y1, x2, y2])

# row accumulation
for i in range(1, N+1):
    for j in range(2,N+1):
        dp[i][j] += dp[i][j-1]
# col accumulation
for i in range(1, N+1):
    for j in range(2, N+1):
        dp[j][i] += dp[j-1][i]

for x1, y1, x2, y2 in target:
    print(dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>dp</category>
      <category>PYTHON</category>
      <category>구간 합 구하기</category>
      <category>동적 프로그래밍</category>
      <category>백준</category>
      <category>백준 11660</category>
      <category>알고리즘</category>
      <category>코딩 테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/361</guid>
      <comments>https://otugi.tistory.com/361#entry361comment</comments>
      <pubDate>Thu, 14 Apr 2022 23:33:07 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2096] 내려가기</title>
      <link>https://otugi.tistory.com/360</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2096&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2096&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1649307661793&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2096번: 내려가기&quot; data-og-description=&quot;첫째 줄에 N(1 &amp;le; N &amp;le; 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2096&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2096&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kxzRq/hyNXxuQJ2O/X70JCIY4RDbmYz5n7ax4Rk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2096&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2096&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kxzRq/hyNXxuQJ2O/X70JCIY4RDbmYz5n7ax4Rk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2096번: 내려가기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 N(1 &amp;le; N &amp;le; 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;DP를 사용하는 문제이다. 메모리 제한이 아주 극심해서 여기에 신경쓰면서 코드를 구현해야 한다. 2차원 리스트로 DP를 구현하면 메모리 초과가 발생하므로 각각의 변수에 저장하도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1649307739855&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/2096

import sys
input = sys.stdin.readline

N = int(input())
dp = [list(map(int, input().split())) for _ in range(N)]

lmax, cmax, rmax = dp[0][0], dp[0][1], dp[0][2]
lmin, cmin, rmin = dp[0][0], dp[0][1], dp[0][2]

for i in range(1, N):
    lmax, cmax, rmax = max(lmax, cmax) + dp[i][0], max(lmax, cmax, rmax) + dp[i][1], max(cmax, rmax) + dp[i][2]
    lmin, cmin, rmin = min(lmin, cmin) + dp[i][0], min(lmin, cmin, rmin) + dp[i][1], min(cmin, rmin) + dp[i][2]

print(max(lmax, cmax, rmax), min(lmin, cmin, rmin))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>dp</category>
      <category>PYTHON</category>
      <category>내려가기</category>
      <category>동적 프로그래밍</category>
      <category>백준</category>
      <category>백준 2096</category>
      <category>백준 내려가기</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/360</guid>
      <comments>https://otugi.tistory.com/360#entry360comment</comments>
      <pubDate>Thu, 7 Apr 2022 14:02:44 +0900</pubDate>
    </item>
    <item>
      <title>[백준 17144] 미세먼지 안녕!</title>
      <link>https://otugi.tistory.com/359</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17144&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/17144&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1649237170249&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;17144번: 미세먼지 안녕!&quot; data-og-description=&quot;미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을&amp;nbsp;크기가&amp;nbsp;R&amp;times;C인 격자판으로 나타냈고, 1&amp;times;1 크기의 칸으로 나눴다. 구사&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/17144&quot; data-og-url=&quot;https://www.acmicpc.net/problem/17144&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Da5kK/hyNVSmkB5y/EKm4VjQphv3G6yvHUCj0o0/img.png?width=1272&amp;amp;height=1140&amp;amp;face=0_0_1272_1140,https://scrap.kakaocdn.net/dn/CMrIo/hyNVQvg7iu/R5wGNpbda6W9CvqceWoRp0/img.png?width=1246&amp;amp;height=1124&amp;amp;face=0_0_1246_1124&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/17144&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/17144&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Da5kK/hyNVSmkB5y/EKm4VjQphv3G6yvHUCj0o0/img.png?width=1272&amp;amp;height=1140&amp;amp;face=0_0_1272_1140,https://scrap.kakaocdn.net/dn/CMrIo/hyNVQvg7iu/R5wGNpbda6W9CvqceWoRp0/img.png?width=1246&amp;amp;height=1124&amp;amp;face=0_0_1246_1124');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;17144번: 미세먼지 안녕!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을&amp;nbsp;크기가&amp;nbsp;R&amp;times;C인 격자판으로 나타냈고, 1&amp;times;1 크기의 칸으로 나눴다. 구사&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼지 확산, 먼지 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 두 가지 함수를 짜면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;확산 함수를 짤 때 유의할 점은 먼지가 이미 있던 곳으로도 확산이 일어난다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼지 이동 함수를 짤 때 유의할 점은 공기청정기를 기준으로 해서 위 아래 순환 방향이 다르다는 점과 공기 청정기로 들어간 먼지는 소멸한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이동 함수를 짤 때 range 설정이 조금 까다롭긴 하나 차근차근 따져보면 풀 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제출은 python3이 시간초과가 나서 &lt;b&gt;pypy3&lt;/b&gt;로 했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1649237288970&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/17144

import sys
input = sys.stdin.readline
import copy

R, C, T = map(int, input().split())
arr = []
for _ in range(R):
    arr.append(list(map(int, input().strip().split())))
circulator = []
for i in range(R):
    for j in range(C):
        if arr[i][j] == -1:
            circulator.append([i,j])

def diff():
    dust_pos = []
    for i in range(R):
        for j in range(C):
            if arr[i][j] &amp;gt;= 1:
                dust_pos.append([i,j,arr[i][j]])
    for r,c,d in dust_pos:
        for dr, dc in ((-1,0),(1,0),(0,-1),(0,1)):
            nr, nc = r + dr, c + dc
            if 0&amp;lt;=nr&amp;lt;R and 0&amp;lt;=nc&amp;lt;C and arr[nr][nc]!=-1:
                arr[nr][nc] += d//5
                arr[r][c] -= d//5

def move():
    temp = copy.deepcopy(arr)
    
    # upper
    y1, x1 = circulator[0]
    arr[y1][1] = 0
    for i in range(2, C):
        arr[y1][i] = temp[y1][i-1]
    for i in range(y1-1, -1, -1):
        arr[i][C-1] = temp[i+1][C-1]
    for i in range(C-2, -1, -1):
        arr[0][i] = temp[0][i+1]
    for i in range(1, y1):
        arr[i][0] = temp[i-1][0]

    # lower
    y2, x2 = circulator[1]
    arr[y2][1] = 0
    for i in range(2, C):
        arr[y2][i] = temp[y2][i-1]
    for i in range(y2+1, R):
        arr[i][C-1] = temp[i-1][C-1]
    for i in range(C-2, -1, -1):
        arr[R-1][i] = temp[R-1][i+1]
    for i in range(R-2, y2, -1):
        arr[i][0] = temp[i+1][0]

for _ in range(T):
    diff()
    move()
ans = 0
for i in range(R):
    ans += sum(arr[i])
print(ans+2)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>Algorithm</category>
      <category>PYTHON</category>
      <category>구현</category>
      <category>미세먼지 안녕</category>
      <category>백준</category>
      <category>백준17144</category>
      <category>시뮬레이션</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/359</guid>
      <comments>https://otugi.tistory.com/359#entry359comment</comments>
      <pubDate>Wed, 6 Apr 2022 18:28:48 +0900</pubDate>
    </item>
    <item>
      <title>[백준 1504] 특정한 최단 경로</title>
      <link>https://otugi.tistory.com/358</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1504&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1504&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1649166256978&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1504번: 특정한 최단 경로&quot; data-og-description=&quot;첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 &amp;le; N &amp;le; 800, 0 &amp;le; E &amp;le; 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1504&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1504&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/NffuU/hyNVSTBuqP/TxAo0lhw9EjKcD9pLPXQGk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1504&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1504&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/NffuU/hyNVSTBuqP/TxAo0lhw9EjKcD9pLPXQGk/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1504번: 특정한 최단 경로&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 &amp;le; N &amp;le; 800, 0 &amp;le; E &amp;le; 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;방법은 두 가지가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;s -&amp;gt; v1 -&amp;gt; v2 -&amp;gt; n&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;s -&amp;gt; v2 -&amp;gt; v1 -&amp;gt; n&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;각 경로가 최소가 되는 것을 찾으면 최종경로 또한 최소가 된다. 따라서 s, v1, v2를 시작점으로 해서 다익스트라 알고리즘을 3번 돌린 뒤에 위 두 경로 중 최단거리를 print하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1649166360487&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/1504
import sys
input = sys.stdin.readline
import heapq
inf = sys.maxsize

N, E = map(int, input().split())
arr = [[] for _ in range(N+1)]

for _ in range(E):
    a, b, c = map(int, input().split())
    arr[a].append([b, c])
    arr[b].append([a, c])
v1, v2 = map(int, input().split())


def dijkstra(start):
    dp = [inf for _ in range(N+1)]
    dp[start] = 0
    hq = []
    heapq.heappush(hq, [0,start])
    while hq:
        w, c = heapq.heappop(hq)
        for n_n, n_w in arr[c]:
            wei = n_w + w
            if dp[n_n] &amp;gt; wei:
                dp[n_n] = wei
                heapq.heappush(hq, [wei, n_n])
    return dp

one = dijkstra(1)
v1_ = dijkstra(v1)
v2_ = dijkstra(v2)
ans = min(one[v1]+v1_[v2]+v2_[N], one[v2]+v2_[v1]+v1_[N])
print(ans if ans&amp;lt;inf else -1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>Dijkstra</category>
      <category>PYTHON</category>
      <category>그래프</category>
      <category>그래프 탐색</category>
      <category>다익스트라</category>
      <category>백준</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>특정한 최단 경로</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/358</guid>
      <comments>https://otugi.tistory.com/358#entry358comment</comments>
      <pubDate>Tue, 5 Apr 2022 22:46:43 +0900</pubDate>
    </item>
    <item>
      <title>[백준 13549] 숨바꼭질 3</title>
      <link>https://otugi.tistory.com/357</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13549&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/13549&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648886631195&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;13549번: 숨바꼭질 3&quot; data-og-description=&quot;수빈이는 동생과&amp;nbsp;숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 &amp;le; N &amp;le; 100,000)에 있고, 동생은 점 K(0 &amp;le; K &amp;le; 100,000)에&amp;nbsp;있다.&amp;nbsp;수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/13549&quot; data-og-url=&quot;https://www.acmicpc.net/problem/13549&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bowXea/hyNUwPm2kk/ljfR1O6429C8PUeiUija20/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13549&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/13549&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bowXea/hyNUwPm2kk/ljfR1O6429C8PUeiUija20/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;13549번: 숨바꼭질 3&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;수빈이는 동생과&amp;nbsp;숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 &amp;le; N &amp;le; 100,000)에 있고, 동생은 점 K(0 &amp;le; K &amp;le; 100,000)에&amp;nbsp;있다.&amp;nbsp;수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우선순위큐를 사용해서 풀면 된다. 큐에 삽입할 때는 시간이 빠른 순서로 정렬될 수 있도록 (시간, 위치)의 순서쌍을 넣어준다. 주의할 점은 삽입하는 순서인데, x 위치에서 가능한 총 경우의 수는 x-1, x+1, 2x의 세 가지이다. 이 때 순간이동을 하는 경우 소요되는 시간이 0초로 가장 짧으므로, &lt;span style=&quot;background-color: #f3c000;&quot;&gt;2x의 위치를 먼저 삽입한 뒤에 방문검사를 해서 x-1, x+1을 넣어주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;가령, 1에서 2로 가는 경우 2x를 먼저 방문하면 0초가 소요되지만 x+1을 먼저 방문하면 1초가 되어 결과값이 최소가 아니게 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1648886776894&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://www.acmicpc.net/problem/13549
import heapq

N, K = map(int, input().split())
visit = [0]*100001
hq = []
heapq.heappush(hq, (0,N))
visit[N] = 1
while hq:
    t, pos = heapq.heappop(hq)
    if pos == K:
        print(t)
        break
    if 0&amp;lt;=2*pos&amp;lt;=100000 and visit[2*pos] == 0:
        heapq.heappush(hq, (t, 2*pos))
        visit[2*pos] = 1
    if 0&amp;lt;=pos-1&amp;lt;=100000 and visit[pos-1] == 0:
        heapq.heappush(hq, (t+1,pos-1))
        visit[pos-1] = 1
    if 0&amp;lt;=pos+1&amp;lt;=100000 and visit[pos+1] == 0:
        heapq.heappush(hq, (t+1,pos+1))
        visit[pos+1] = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/백준</category>
      <category>BFS</category>
      <category>PYTHON</category>
      <category>백준</category>
      <category>숨바꼭질</category>
      <category>알고리즘</category>
      <category>우선순위큐</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/357</guid>
      <comments>https://otugi.tistory.com/357#entry357comment</comments>
      <pubDate>Sat, 2 Apr 2022 17:05:36 +0900</pubDate>
    </item>
    <item>
      <title>허깅페이스(Huggingface) transformers로 early stopping 사용하기</title>
      <link>https://otugi.tistory.com/356</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;허깅페이스의 transformers 패키지를 사용하는데 early stopping 방식으로 학습을 시키고 싶을 땐 아래와 같이 early stopping callback을 넣어주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1648432058041&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from transformers import EarlyStoppingCallback

batch_size = 3
args = Seq2SeqTrainingArguments(
   &quot;saved_model&quot;,
   evaluation_strategy = &quot;steps&quot;,
   eval_steps = 5,
   load_best_model_at_end = True,
   learning_rate=2e-5,
   per_device_train_batch_size=batch_size,
   per_device_eval_batch_size=batch_size,
   gradient_accumulation_steps=2,
   weight_decay=0.01,
   save_total_limit=3,
   num_train_epochs=5,
   predict_with_generate=True,
   fp16=False,
   report_to='wandb',
   run_name=&quot;ut_del_three_per_each_ver2_early_stop_4&quot;  # name of the W&amp;amp;B run (optional)
)
trainer = Seq2SeqTrainer(
   model,
   args,
   train_dataset=tokenized_datasets[&quot;train&quot;],
   eval_dataset=tokenized_datasets[&quot;validation&quot;],
   data_collator=data_collator,
   tokenizer=tokenizer,
   compute_metrics=compute_metrics,
   callbacks = [EarlyStoppingCallback(early_stopping_patience=2)]
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 파라미터는 임의로 바꾸어도 되지만 아래의 4가지는 꼭 지정해주어야 한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;load_best_model_at_end = True&lt;span&gt;&amp;nbsp;&lt;/span&gt;(EarlyStoppingCallback()&lt;span&gt;&amp;nbsp;&lt;/span&gt;requires this to be&lt;span&gt;&amp;nbsp;&lt;/span&gt;True).&lt;/li&gt;
&lt;li&gt;evaluation_strategy&lt;span&gt;&amp;nbsp;&lt;/span&gt;=&lt;span&gt;&amp;nbsp;&lt;/span&gt;'steps'&lt;span&gt;&amp;nbsp;&lt;/span&gt;instead of&lt;span&gt;&amp;nbsp;&lt;/span&gt;'epoch'.&lt;/li&gt;
&lt;li&gt;eval_steps&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 50 (evaluate the metrics after N steps).&lt;/li&gt;
&lt;li&gt;metric_for_best_model = 'f1',&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;metric_for_best_model은 지정해주지 않으면 기본적으로 validation loss가 default이다. 즉, loss를 보고서 early stopping을 할 지점을 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고로, early stopping은 훈련 단위가 step이기 때문에 오히려 epoch으로 훈련한 경우보다 test 성능이 더 안좋게 나오는 경우도 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>early stopping</category>
      <category>huggingface</category>
      <category>TRANSFORMER</category>
      <category>조기종료</category>
      <category>트랜스포머</category>
      <category>허깅페이스</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/356</guid>
      <comments>https://otugi.tistory.com/356#entry356comment</comments>
      <pubDate>Mon, 28 Mar 2022 10:51:34 +0900</pubDate>
    </item>
    <item>
      <title>2022 Google kickstart Round A 참가 후기</title>
      <link>https://otugi.tistory.com/355</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;한국 시간으로 지난 주 일요일(3.20)에 있었던 킥스타트 Round A에 참가했다. 최종적으로는 4문제 중 2개를 풀었다. 그래도 지난 번 처음 참가했을 때 1개밖에 풀지 못했던 것과 비교하면 나름 선방한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1, 2번 문제는 어렵지는 않았는데 시간초과가 나지 않도록 잘 짜는 것이 관건이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Speed Typing&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문제 :&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7021&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648217300442&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7021&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7021&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/q45qT/hyNPRsrr0x/7u6oogCCD7ssBzYQWPUAT0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7021&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/q45qT/hyNPRsrr0x/7u6oogCCD7ssBzYQWPUAT0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;P 문자열을 I 문자열로 만드는 문제이다. P 문자열에서 글자를 삭제해서 I 문자열을 만들어야 하는데 불가능한 경우 &quot;IMPOSSIBLE&quot;을 출력하면 된다. 나의 경우 먼저 IMPOSSIBLE한 경우를 분석해 먼저 검사하도록 하였다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1648217201720&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def sol():
    I = input()
    P = input()
    I_dict, P_dict = {}, {}
    for a in I:
        if a not in I_dict:
            I_dict[a] = 0
        I_dict[a] += 1
    for a in P:
        if a not in P_dict:
            P_dict[a] = 0
        P_dict[a] += 1
    I_set, P_set = set(list(I)), set(list(P))
    if I_set - P_set:
        return &quot;IMPOSSIBLE&quot;
    for a in I_dict:
        if P_dict[a] &amp;lt; I_dict[a]:
            return &quot;IMPOSSIBLE&quot;
    i, j = 0, 0
    cnt = 0
    while i&amp;lt;len(I) and j&amp;lt;len(P):
        if I[i]==P[j]:
            i += 1
            j += 1
            cnt += 1
        else:
            j += 1
    if cnt != len(I):
        return &quot;IMPOSSIBLE&quot;
    else:
        return len(P)-len(I)

for t in range(int(input())):
    print(f&quot;Case #{t+1}: &quot;+str(sol()))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Challenge Nine&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문제 :&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7997&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7997&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648217450743&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7997&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7997&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/F3dZM/hyNPLMwXM6/TMa1wlkdX3xPEWY2kVBxW0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7997&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000008cb33e/00000000009e7997&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/F3dZM/hyNPLMwXM6/TMa1wlkdX3xPEWY2kVBxW0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주어진 수에 0-9까지의 수 중 1개의 digit을 추가해서 가능한 가장 작은 9의 배수로 만드는 문제였다. 9의 배수의 경우 각 digit의 합이 9의 배수여야 한다는 성질을 이용해 구현하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1648217435786&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

def sol():
    num = input().strip()
    num_sum = sum(list(map(int, list(num))))

    if num_sum % 9 == 0:
        return int(num[0]+'0'+num[1:])
    else:
        p = (num_sum // 9 + 1)*9 - num_sum
        # ans = min(int(str(p)+num), int(num+str(p)))
        # for i in range(1, len(num)):
        #     ans = min(ans, int(num[:i]+str(p)+num[i:]))
        ans = 0
        for i in range(len(num)):
            if p &amp;lt; int(num[i]):
                ans = int(num[:i] + str(p) + num[i:])
                break
        if ans == 0:
            ans = int(num+str(p))

        return ans

for t in range(int(input().strip())):
    print(f&quot;Case #{t+1}: &quot;+str(sol()))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3번과 4번 중 고민하다 배점이 더 큰 4번을 먼저 손댔는데....&lt;s&gt;그러지말걸&lt;/s&gt;....&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;무튼 다음 번 참가할 땐 3개를 푸는 걸 목표로 해서 공부를 꾸준히 해야겠다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이렇게 1개씩 늘리다보면 언젠가 4개 다 풀겠지!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Contest</category>
      <category>challenge nine</category>
      <category>google coding competition</category>
      <category>kick start</category>
      <category>kickstart</category>
      <category>speed typing</category>
      <category>구글 킥스타트</category>
      <category>알고리즘</category>
      <category>킥스타트</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/355</guid>
      <comments>https://otugi.tistory.com/355#entry355comment</comments>
      <pubDate>Fri, 25 Mar 2022 23:14:28 +0900</pubDate>
    </item>
    <item>
      <title>텍스트로부터 키워드 추출하기(KeyBERT)</title>
      <link>https://otugi.tistory.com/352</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;연구 주제와 관련하여 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;텍스트에서 키워드를 추출&lt;/span&gt;해야 할 일이 있었다. 이를 위해 BERT embedding을 사용한 KeyBERT를 써보았는데 관련하여 방법을 정리해둔다. 여기서 설명하지는 않지만 여러 문서에서의 키워드를 추출하는 방법, 키워드 추출의 diversity를 부여하는 방법 등이 공식 문서에 나와있다. 이 외에도 다양한 옵션을 사용할 수 있다. 공식 문서는 &lt;a href=&quot;https://maartengr.github.io/KeyBERT/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이곳&lt;/a&gt;을 참고하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;사용 방법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사용 방법은 간단하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645449460422&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from keybert import KeyBERT

doc = &quot;&quot;&quot;
         Supervised learning is the machine learning task of learning a function that
         maps an input to an output based on example input-output pairs. It infers a
         function from labeled training data consisting of a set of training examples.
         In supervised learning, each example is a pair consisting of an input object
         (typically a vector) and a desired output value (also called the supervisory signal). 
         A supervised learning algorithm analyzes the training data and produces an inferred function, 
         which can be used for mapping new examples. An optimal scenario will allow for the 
         algorithm to correctly determine the class labels for unseen instances. This requires 
         the learning algorithm to generalize from the training data to unseen situations in a 
         'reasonable' way (see inductive bias).
      &quot;&quot;&quot;
kw_model = KeyBERT()
keywords = kw_model.extract_keywords(doc)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 같이 KeyBERT 모델을 load하고 키워드를 추출하고자 하는 텍스트를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;extract_keywords()&lt;/span&gt; 메소드의 input으로 넣어주면 된다. output은 아래와 같이 리스트의 형태로 나오게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645449636431&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[('learning', 0.4604),
 ('algorithm', 0.4556),
 ('training', 0.4487),
 ('class', 0.4086),
 ('mapping', 0.3700)]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 요소의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;0번째 문자열이 키워드고, 1번째 수는 해당 키워드가 문서를 얼마나 대표하는지에 대한 수치&lt;/span&gt;를 나타낸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;Sentence Embedding Model 선택&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1645449724147&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from keybert import KeyBERT
kw_model = KeyBERT(model=&quot;all-MiniLM-L6-v2&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 같이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;model 파라미터를 통해 문장 임베딩 모델을 선택&lt;/span&gt;할 수 있다. 사용할 수 있는 여러 모델들이 있는데 이와 관련해서는 &lt;a href=&quot;https://www.sbert.net/docs/pretrained_models.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이곳&lt;/a&gt;을 참고하면 된다. 링크를 통해 접속하면 아래와 같이 사용할 수 있는 여러 sentence embedding model들이 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QFReO/btrtRDCyVeW/wF0dcxqS9xYI2K45IaygR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QFReO/btrtRDCyVeW/wF0dcxqS9xYI2K45IaygR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QFReO/btrtRDCyVeW/wF0dcxqS9xYI2K45IaygR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQFReO%2FbtrtRDCyVeW%2FwF0dcxqS9xYI2K45IaygR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1188&quot; height=&quot;529&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아무것도 지정해주지 않으면 default값은 &quot;all-MiniLM-L6-v2&quot;가 된다. 여기서 성능이나 처리 속도를 보고 용도에 맞게 골라 사용하면 된다. (공식 문서에서는 영어를 사용하는 경우 되도록이면 &quot;all-MiniLM-L6-v2&quot;을 사용하라고 한다. 아마 성능이 준수하고 그에 비해 속도가 타모델보다 많이 빠르기 때문인 것 같다.) 다른 모델도 시도해보았는데 사실 default로 해도 왠만큼 준수하게 키워드가 잘 뽑힌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;추출할 키워드 갯수 지정해주기, 불용어(stopwords) 제거&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아래와 같이 extract_keywords() 메소드의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;top_n 파라미터를 지정해주면 해당 갯수만큼의 키워드를 추출&lt;/span&gt;할 수 있다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;stop_words 파라미터를 지정해주면 불용어를 제거&lt;/span&gt;하고 키워드를 추출할 수 있다.(default는 'english')&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645450075197&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from keybert import KeyBERT

doc = &quot;&quot;&quot;
         Supervised learning is the machine learning task of learning a function that
         maps an input to an output based on example input-output pairs. It infers a
         function from labeled training data consisting of a set of training examples.
         In supervised learning, each example is a pair consisting of an input object
         (typically a vector) and a desired output value (also called the supervisory signal). 
         A supervised learning algorithm analyzes the training data and produces an inferred function, 
         which can be used for mapping new examples. An optimal scenario will allow for the 
         algorithm to correctly determine the class labels for unseen instances. This requires 
         the learning algorithm to generalize from the training data to unseen situations in a 
         'reasonable' way (see inductive bias).
      &quot;&quot;&quot;
kw_model = KeyBERT()
keywords = kw_model.extract_keywords(doc, top_n=7, stop_words='english')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>keybert</category>
      <category>keyword</category>
      <category>keyword extract</category>
      <category>keyword extraction</category>
      <category>sentence transformer</category>
      <category>키워드</category>
      <category>키워드 추출</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/352</guid>
      <comments>https://otugi.tistory.com/352#entry352comment</comments>
      <pubDate>Mon, 21 Feb 2022 22:33:47 +0900</pubDate>
    </item>
    <item>
      <title>허깅페이스(Huggingface) custom loss로 Trainer 학습시키기</title>
      <link>https://otugi.tistory.com/351</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;허깅페이스의 transformers 패키지를 사용할 때 custom loss로 최적화를 해야하는 경우가 있다. 이럴 땐 Trainer클래스를 상속받아 새로운 CustomTrainer 클래스를 만들고 그 안의 compute_loss 함수를 새로 작성해주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1643349382474&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from torch import nn
from transformers import Trainer


class CustomTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        labels = inputs.get(&quot;labels&quot;)
        # forward pass
        outputs = model(**inputs)
        logits = outputs.get(&quot;logits&quot;)
        # compute custom loss (suppose one has 3 labels with different weights)
        loss_fct = nn.CrossEntropyLoss(weight=torch.tensor([1.0, 2.0, 3.0]))
        loss = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))
        return (loss, outputs) if return_outputs else loss&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;compute_loss 내에서 본인이 원하는 loss를 구해 최적화하도록 코드를 바꿔주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>custom loss</category>
      <category>huggingface</category>
      <category>Trainer</category>
      <category>Transformers</category>
      <category>손실함수</category>
      <category>허깅페이스</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/351</guid>
      <comments>https://otugi.tistory.com/351#entry351comment</comments>
      <pubDate>Fri, 28 Jan 2022 14:59:22 +0900</pubDate>
    </item>
    <item>
      <title>[AI/ML] 배치(batch)와 에폭(epoch), 적절한 배치 사이즈(batch size)</title>
      <link>https://otugi.tistory.com/350</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;많이들 헷갈리는 개념 중 하나가 바로 배치(batch)와 에폭(epoch)이다. 둘은 서로 다른 개념이지만 모두 학습의 성능을 결정하는 중요한 요소이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;배치와 에폭의 개념&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;딥러닝에서 모델이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;전체 학습 데이터를 한 번씩 본 것&lt;/span&gt;을 '에폭을 돌았다'라고 표현한다. 모델은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;가중치를 한 번 업데이트하기 위해 한 개 이상의 훈련 데이터 묶음&lt;/span&gt;을 사용하는데, 이것을 배치라고 하고 이 묶음의 사이즈가 바로 배치 사이즈(batch size)이다. 따라서 배치 사이즈에 따라 에폭 당 훈련 횟수가 달라진다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lh3bH/btrrUP58aaF/GsdkjmincJYrqPoh9e2jek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lh3bH/btrrUP58aaF/GsdkjmincJYrqPoh9e2jek/img.png&quot; data-alt=&quot;배치와 에폭. 여러 개의 배치가 모여 1 에폭을 형성한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lh3bH/btrrUP58aaF/GsdkjmincJYrqPoh9e2jek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flh3bH%2FbtrrUP58aaF%2FGsdkjmincJYrqPoh9e2jek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;134&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배치와 에폭. 여러 개의 배치가 모여 1 에폭을 형성한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;배치 크기와 모델 훈련 시간의 관계&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;100개의 훈련 데이터를 가지고 80에폭 동안 훈련시킨다고 가정해보자.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배치 크기=1이면, 모델은 1에폭 당 100번 훈련(가중치 업데이트), 총 8000번 훈련&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배치 크기=10이면, 모델은 1에폭 당 10번 훈련, 총 800번 훈련&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배치 크기=100이면, 모델은 1에폭 당 1번 훈련, 총 80번 훈련&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;즉, 배치 크기를 키우면 1에폭 당 훈련 수가 감소하고 이로 인해 전체 훈련 횟수가 감소하여 결과적으로 전체 훈련 시간이 감소하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;배치 크기가 학습에 미치는 영향&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;딥러닝에선 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;입력 데이터가 전체 훈련 데이터를 대표&lt;/span&gt;한다고 가정한다. 즉, 한 배치에 포함되는 데이터가 전체 훈련 데이터를 얼마나 잘 표현하느냐에 따라 학습의 안정성이 결정된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;i&gt;&lt;b&gt;배치 크기가 매우 작다면?&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;데이터셋 크기=N, 배치 크기=1이라면 최적화 함수는 하나의 학습 데이터마다 오차를 계산하면서 모델의 가중치를 1에폭 당 N번 갱신하게 된다. 각각의 데이터 샘플을 꼼꼼하게 살펴보며 학습이 진행되지만, 특이값(outlier)에 따라 가중치 업데이트 과정에서 최적화 탐색 경로를 크게 벗어날 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/67FRQ/btrrTiAYKF0/d3u79UhEziJecamGdmR3eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/67FRQ/btrrTiAYKF0/d3u79UhEziJecamGdmR3eK/img.png&quot; data-alt=&quot;배치 사이즈에 따라 서로 다른 최적화 경로 탐색 양상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/67FRQ/btrrTiAYKF0/d3u79UhEziJecamGdmR3eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F67FRQ%2FbtrrTiAYKF0%2Fd3u79UhEziJecamGdmR3eK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;266&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배치 사이즈에 따라 서로 다른 최적화 경로 탐색 양상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;i&gt;&lt;b&gt;배치 크기가 매우 크다면?&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;반대로 배치 크기가 매우 크다면 어떨까? 데이터셋 크기=N, 배치 크기=N이라면 모델 가중치는 1에폭 당 1번 갱신된다. 즉, 주어진 모든 훈련 데이터의 평균 특성을 바탕으로 한 번의 훈련만으로 최적의 가중치 조합을 찾아간다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;배치 크기 딜레마 : 배치 크기가 크면 빠르고 효과적으로 최적화가 이루어질까?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;답은 NO이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;최적화를 진행하다가 극소값이나 안장점에 빠지게 될 수 있다. 그런데 최적화 함수는 gradient 기반의 방식을 사용해 최적화를 진행하므로 이것이 최소값이 아님을 알지 못한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;loss가 최소값임을 보장할 수 없는 극소값 또는 안장점 근처에 도달하게 되면 배치 크기가 큰 상황에선 이 구간을 빠져나오기가 어렵다. 배치 크기가 큰 경우 전체 훈련 데이터의 평균적인 특성을 바탕으로 학습을 진행하여 gradient를 크게 크게 바꾸지 못하기 때문이다. (쉽게 말해 평균을 구하게 되면 특이값이 전체의 보편적인 값에 파묻혀 영향력이 작아진다.) 반면, 배치 크기가 작을 때는 이 구간에서 빠져나오기가 훨씬 수월하다. 보통 처음 학습을 진행할 때에는 해당 도메인에서 일반적으로 자주 사용되는 배치 크기를 기준으로 하여 최적의 값을 탐색한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pGLVN/btrrVngZYuI/JcckMPh25Ho8dr2fhKGk11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pGLVN/btrrVngZYuI/JcckMPh25Ho8dr2fhKGk11/img.png&quot; data-alt=&quot;배치 크기가 크면 최소값을 찾지 못하고 극소값이나 안장점에 빠지게 될 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pGLVN/btrrVngZYuI/JcckMPh25Ho8dr2fhKGk11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpGLVN%2FbtrrVngZYuI%2FJcckMPh25Ho8dr2fhKGk11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;379&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배치 크기가 크면 최소값을 찾지 못하고 극소값이나 안장점에 빠지게 될 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;즉, 적절한 배치 크기는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;학습 속도&lt;/span&gt;와 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;학습 성능&lt;/span&gt; 모두에 영향을 미치는 중요한 요소이다. 그러므로 학습 시에 여러 실험을 통해 해당 실험에 가장 적합한 배치 크기를 정해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;참고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.kakaobrain.com/blog/113&quot;&gt;https://www.kakaobrain.com/blog/113&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>AI/AI 개념</category>
      <category>batch</category>
      <category>batch size</category>
      <category>epoch</category>
      <category>ML 모델 학습</category>
      <category>모델 학습</category>
      <category>배치</category>
      <category>배치 사이즈</category>
      <category>배치 최적화</category>
      <category>배치 크기</category>
      <category>에폭</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/350</guid>
      <comments>https://otugi.tistory.com/350#entry350comment</comments>
      <pubDate>Thu, 27 Jan 2022 20:33:03 +0900</pubDate>
    </item>
    <item>
      <title>허깅페이스(Huggingface)로 내 모델 포팅(porting)하기</title>
      <link>https://otugi.tistory.com/349</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1642680798475&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Hugging Face &amp;ndash; The AI community building the future.&quot; data-og-description=&quot;The AI community building the future. Build, train and deploy state of the art models powered by the reference open source in machine learning.&quot; data-og-host=&quot;huggingface.co&quot; data-og-source-url=&quot;https://huggingface.co/&quot; data-og-url=&quot;https://huggingface.co/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bkvMkS/hyM9oeOr1q/A9c3FcUea4XIKOnrS1jZI1/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648&quot;&gt;&lt;a href=&quot;https://huggingface.co/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://huggingface.co/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bkvMkS/hyM9oeOr1q/A9c3FcUea4XIKOnrS1jZI1/img.png?width=1200&amp;amp;height=648&amp;amp;face=0_0_1200_648');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Hugging Face &amp;ndash; The AI community building the future.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The AI community building the future. Build, train and deploy state of the art models powered by the reference open source in machine learning.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;huggingface.co&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://huggingface.co/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;허깅페이스(Huggingface)&lt;/a&gt;는 사람들이 모델을 만들고 학습시켜 올려둘 수 있는 저장소이다. 기본적으로는 git을 기반으로 돌아간다. 허깅페이스의 transformers 모듈을 사용하면 자신에게 필요한 여러 모델들을 손쉽게 가져다 쓸 수 있다. 여기에 자기가 만들어 학습을 시킨 혹은 기존의 pre-trained된 모델을 가져다가 fine-tuning시킨 모델을 자신의 저장소에 업로드해둘 수 있다. 그러면 손쉽게 다음번에 사용할 수도 있고, 다른 사람들을 위해 배포할 수도 있다. 허깅페이스에 자신의 모델을 포팅하는 방법을 알아보자!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;git LFS 설치&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위에서 허깅페이스는 기본적으로 Git을 통해 저장소로 업로드한다고 했었다. 그런데 git은 최대 100MB로 업로드 파일 사이즈 제한이 있다. 일반적으로 학습시키는 모델의 경우 이보다 용량이 큰 경우가 많으니 이를 위해서 먼저 Git LFS(Large File Storage)를 설치해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1642680401291&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt-get install git-lfs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;모델 포팅하기&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모델의 학습이 모두 끝난 뒤 아래의 코드를 넣어주면 된다. MODEL_SAVE_REPO는 자신이 저장하려는 저장소의 이름(예컨대, 아래의 경우 bart-base-samsum이라는 이름의 레포지토리에 모델이 저장된다.)이고, HUGGINGFACE_AUTO_TOKEN은 사이트에서 발급받은 자신의 고유 토큰이다. 주석처리해둔 사이트로 이동하여 발급받을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아래 코드를 실행시키고나면 어느 정도 시간이 지난 뒤(모델 크기가 크면 오래 걸린다) 허깅페이스에 자신의 모델이 업로드된 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1642680084773&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# repo
MODEL_SAVE_REPO = 'bart-base-samsum'
HUGGINGFACE_AUTH_TOKEN = 'your auth token' # https://huggingface.co/settings/token

# Push to huggingface-hub
model.push_to_hub(
MODEL_SAVE_REPO,
use_temp_dir=False,
use_auth_token=HUGGINGFACE_AUTH_TOKEN
)

tokenizer.push_to_hub(
MODEL_SAVE_REPO,
use_temp_dir=False,
use_auth_token=HUGGINGFACE_AUTH_TOKEN
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 from_pretrained('PSW/bart-base/samsum')과 같이 자신이 만들어 학습시킨 모델(토크나이저까지도)을 다음 번에 손쉽게 재사용할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>AI 모델</category>
      <category>hugging face</category>
      <category>huggingface</category>
      <category>ML 모델</category>
      <category>ML 모델 저장</category>
      <category>model porting</category>
      <category>모델 저장</category>
      <category>모델 포팅</category>
      <category>허깅페이스</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/349</guid>
      <comments>https://otugi.tistory.com/349#entry349comment</comments>
      <pubDate>Thu, 20 Jan 2022 21:13:26 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round D Cutting Intervals 풀이</title>
      <link>https://otugi.tistory.com/348</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933#problem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933#problem&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1641992736808&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933#problem&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933#problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/chT0fJ/hyM5BqhZrP/2HaRtcvXOsMaDrSzUkQVmK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933#problem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933#problem&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/chT0fJ/hyM5BqhZrP/2HaRtcvXOsMaDrSzUkQVmK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보통 이런 문제는 그리디 방식으로 풀면 되고, 시간복잡도를 고려하면 중간의 range가 아닌 각 구간의 양 끝단에만 집중하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;(1,3), (2,4), (1,4)가 input으로 주어지고 C가 3인 경우를 가정해보자(문제에서 주어진 sample case) 몇 가지 관찰이 필요한 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 각 구간의 양 끝단은 cut하여도 전체 interval 갯수에 변화가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 해당 지점을 cut하였을 때 새로 생기는 interval의 갯수는 해당 지점에 영향을 받는 interval의 갯수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. a~b 사이에 가능한 possible_cut은 b-a만큼 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각 구간의 (시작점+1)엔 1을 더해주고 (끝점)엔 -1을 더해준다. 위의 예시로 구해보면 [(2,2), (3,0), (4,-2)]가 된다. 각 순서쌍에서 첫번째 수가 해당 position을 나타낸다. 1에서 시작하는 구간이 2개니까 (2,2) 2에서 시작하는 구간이 1개, 3에서 끝나는 구간이 1개니까 (3,0) 4에서 끝나는 구간이 2개니까 (4,-2)가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이를 해석해보면 2~3까지는 영향을 받는 line이 2개이고, 해당 구간에서 가능한 cut의 갯수는 3-2=1개이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이를 토대로 각 지점 사이마다 몇 개의 interval이 영향을 받는지를 알 수 있고 위에서 서술한 관찰 2를 통해 해당 구간에서 가능한 cut에 따른 새로 생성되는 interval을 계산할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문제의 조건은 가장 많은 interval을 만들어내는 것이므로 영향을 받는 interval의 갯수에 따라 내림차순으로 정렬하여 탐색해 나가면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1641993411608&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/00000000004361e3/000000000082b933

from collections import Counter

def cuttingIntervals():
    N, C = map(int, input().split())
    intervals = []
    for _ in range(N):
        s, e = map(int, input().split())
        intervals.append((s,e))

    pos_lines = {}
    for s, e in intervals:
        if s+1 not in pos_lines:
            pos_lines[s+1] = 0
        pos_lines[s+1] += 1
        if e not in pos_lines:
            pos_lines[e] = 0
        pos_lines[e] -= 1
    pos_lines = sorted(pos_lines.items())
    # print(pos_lines)

    cuts_lines = []
    affected_lines = 0
    for i in range(len(pos_lines)-1):
        affected_lines += pos_lines[i][1]
        possible_cuts = pos_lines[i+1][0] - pos_lines[i][0]
        cuts_lines.append((affected_lines, possible_cuts))
    cuts_lines = sorted(cuts_lines, reverse=True)
    
    ans = N
    for lines, cuts in cuts_lines:
        if cuts&amp;lt;=C:
            ans += lines * cuts
            C -= cuts
        else:
            ans += lines * C
            break
    return ans


for t in range(int(input())):
    print(f&quot;Case #{t+1}: &quot; + str(cuttingIntervals()))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>cutting interval</category>
      <category>google coding competition</category>
      <category>google kick start</category>
      <category>greedy</category>
      <category>kickstart</category>
      <category>구글 킥스타트</category>
      <category>그리디</category>
      <category>킥스타트</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/348</guid>
      <comments>https://otugi.tistory.com/348#entry348comment</comments>
      <pubDate>Wed, 12 Jan 2022 22:18:32 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round B Consecutive Primes 풀이</title>
      <link>https://otugi.tistory.com/347</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1641622190258&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ddKuku/hyM0F2yFie/GtQquoe1NKOd2thGrNVoCK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ddKuku/hyM0F2yFie/GtQquoe1NKOd2thGrNVoCK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 문제에서의 핵심은 주어진 조건 Z의 상한이 10^8인데 1~10^8까지의 소수를 모두 구할 필요가 없다는 것이다. 또한 탐색을 할 때에 sqrt(Z)부터 순차적으로 감소시키며 탐색해야 시간을 줄일 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예컨대, 연속한 두 소수 5와 7의 곱은 35이다. 그런데 거꾸로 이 35가 어떠한 두 연속된 소수를 곱해서 나왔는지를 알아보려고 한다. 그러면 sqrt(35) = 5.xxx인데 5, 4, 3, 2 이러한 순서로 탐색을 해나아가야 한다. 다른 예시로, 연속된 두 소수 11과 13의 곱은 143이다. 거꾸로 어떤 두 연속된 소수를 곱해 143을 만들 수 있는지 탐색하려면 sqrt(143)=11.xxx이므로 11부터 10, 9, 8,... 이러한 순서로 탐색해 나가야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;왜 그럴까? 핵심은 &quot;연속된&quot; 두 소수의 곱을 찾는 문제이므로 sqrt(Z)인 두 수를 곱해 Z가 된다면 이 때부터는 연속한 두 소수를 곱할 수가 없게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1641622565699&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b/000000000077a8e6

def isPrime(n):
    for i in range(2, int(n**0.5)+1):
        if n%i == 0:
            return False
    return True

def CP():
    Z = int(input())
    for first in range(int(Z**0.5), 1, -1):
        if isPrime(first):
            second = first + 1
            while not isPrime(second):
                second += 1
            if first * second &amp;lt;= Z:
                return first * second

for t in range(int(input())):
    print(f'Case #{t+1}: ', CP())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>consecutive prime</category>
      <category>consecutive primes</category>
      <category>google coding competition</category>
      <category>google kickstart</category>
      <category>kick start</category>
      <category>Round B</category>
      <category>구글 코딩 컴페티션</category>
      <category>구글 킥스타트</category>
      <category>킥스타트</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/347</guid>
      <comments>https://otugi.tistory.com/347#entry347comment</comments>
      <pubDate>Sat, 8 Jan 2022 15:16:38 +0900</pubDate>
    </item>
    <item>
      <title>RepSum : Unsupervised Dialogue Summarization based on Replacement Strategy(ACL 2021) 논문 리뷰</title>
      <link>https://otugi.tistory.com/346</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;paper link : &lt;a href=&quot;https://aclanthology.org/2021.acl-long.471.pdf&quot;&gt;https://aclanthology.org/2021.acl-long.471.pdf&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Overview&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Dialogue summarization에서 일반적인 text summarization과 비교했을 때 어려운 점은 바로 training data가 부족하다는 것이다. 이 논문은 이러한 문제를 unsupervised 학습으로 해결하고자 시도하였다. 논문의 핵심 아이디어는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superior summary approximates a replacement of the original dialogue, and they are roughly equivalent for auxiliary tasks.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;즉, 좋은 요약본은 원문의 데이터들을 충분히 가지고 있으므로 여러 task에서 원래의 dialogue를 충분히 대체할 수 있다는 점에 착안하여 요약의 성능을 높이는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;How it works?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx1Bhm/btrpKkU7Dhf/MHGUay33fMaWHg1ywrAMK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx1Bhm/btrpKkU7Dhf/MHGUay33fMaWHg1ywrAMK1/img.png&quot; data-alt=&quot;RepSum의 개략적인 아이디어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx1Bhm/btrpKkU7Dhf/MHGUay33fMaWHg1ywrAMK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx1Bhm%2FbtrpKkU7Dhf%2FMHGUay33fMaWHg1ywrAMK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;585&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;585&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RepSum의 개략적인 아이디어&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 이러한 RepSum은 어떤 방식일까? 개략적인 로직은 위의 그림과 같다. 먼저 dialogue를 기반으로 summary를 생성한다. 그 후 original dialogue와 summary에서 각각 n번째 utterance를 predict한다. 이 둘의 차이를 최소화 하도록 학습을 진행시킨다. 조금 더 디테일하게는 아래의 그림과 같이 구성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnnU7a/btrpJYqFg7R/V8QRb4zFHunK7QpLtGct0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnnU7a/btrpJYqFg7R/V8QRb4zFHunK7QpLtGct0K/img.png&quot; data-alt=&quot;구체적인 RepSum의 동작과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnnU7a/btrpJYqFg7R/V8QRb4zFHunK7QpLtGct0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnnU7a%2FbtrpJYqFg7R%2FV8QRb4zFHunK7QpLtGct0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;608&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구체적인 RepSum의 동작과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;dialogue로부터 extractive, abstractive 두 가지 방식으로부터 각각의 summary를 만들어 낸다. 그 후 이들을 가지고 n번째 utterance에 대한 generation과 classification task를 수행한다. generation task는 말 그대로 n번째 utterance를 생성해내는 것이고, classification task는 n번째 utterance를 주어진 선택지 중에 고르는 task이다. 위 그림에서 TG가 바로 Text Generation task를, TC가 Text Classification task를 가리킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 이렇게 만들어진 결과를 가지고 최적화를 진행해야 한다. 그림에서 가장 아래 박스 두 개가 있는데 이는 각각 원문으로부터의 task 수행 결과와 요약문으로부터의 task 수행 결과 사이에 차이를 구해 이를 최소화하는 것을 나타낸다. 논문에선 이를 KL divergence를 사용해 구했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2개의 Task&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;&lt;b&gt;Text Generation(TG)&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TG에서의 목표는 n번째 utterance를 생성해내는 것이다. 이를 위해 논문에선 Encoder로 bi-directional LSTM을, Decoder로는 uni-directional LSTM을 사용하였다. 전체 dialogue를 concatenate하여 document로 인코딩하고, attention을 활용해 n번째 utterance를 디코딩하였다. TG에서의 loss function은 아래와 같이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZjwuA/btrpP3kewha/iZSfEqjwtwai2WDkTy2jQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZjwuA/btrpP3kewha/iZSfEqjwtwai2WDkTy2jQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZjwuA/btrpP3kewha/iZSfEqjwtwai2WDkTy2jQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZjwuA%2FbtrpP3kewha%2FiZSfEqjwtwai2WDkTy2jQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;677&quot; height=&quot;90&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;&lt;b&gt;Text Classification(TC)&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TC에서의 목표는 n번째 utterance로 가장 적절한 것을 K개의 후보군 중에 select하는 것이다. Encoder로는 bi-directional LSTM을 사용하였고, 이는 classification task이므로 decoder는 필요하지 않다. dialogue 원문과 summary를 encoder를 통과시켜 만든 representation을 h라고 하고 candidate들을 encoder를 통과시켜 만든 representation을 c라고 한다면 h와 c를 concatenate한 뒤 classifier를 거치도록 구성하였다. TC에서의 loss는 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRNc7o/btrpz2HrW3I/K52DH3rVM31zz9OmU1Wki1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRNc7o/btrpz2HrW3I/K52DH3rVM31zz9OmU1Wki1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRNc7o/btrpz2HrW3I/K52DH3rVM31zz9OmU1Wki1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRNc7o%2Fbtrpz2HrW3I%2FK52DH3rVM31zz9OmU1Wki1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;662&quot; height=&quot;105&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Unsupervised summarization&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;논문에선 추출요약과 생성요약 두 가지 방식 모두에 대해 실험을 진행하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;&lt;b&gt;Extractive&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;추출 요약으로는 SummaRunner(Nallapati et al., 2017)와 유사한 방식으로 sentence binary classification을 수행하였다. dialouge 내에서 각 문장마다 binary label을 부여하는 것인데 요약문에 포함시키고자 하는 문장은 1로, 그렇지 않은 문장은 0으로 분류하는 것이다. label이 없기 대문에 이러한 결과를 TG, TC task를 통해 요약 성능을 최적화 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;&lt;b&gt;Abstractive&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적인 encoder-decoder 구조를 사용해 생성 요약을 구성하였다. softmax probability distribution으로부터 각 단어를 sampling하였다. 그런데 이러한 text 생성 시에 통상 argmax를 사용해 확률이 가장 높은 단어를 선택하는 방식을 사용하는데 이는 non-differentiable한 특성을 갖는다. 그러나 TC, TG task를 거친 후에 역전파를 통해 파라미터를 갱신하는 최적화 과정을 거치도록 해줘야 하므로 본 논문에선 ST Gumble Estimator라는 것을 사용하였다.(짧게 설명하자면 이처럼 argmax를 사용해 미분불가능한 특성을 갖는 모델에 사용할 수 있는 방법이다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Dataset&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AMI dataset : meeting dataset in English&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;100 hours of meeting recordings&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;high-quality&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;manually produced transcription, dialogue acts, topic segmentation, extractive/abstractive summaries&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Justice dataset : court debate records in Chinese&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;30,000 dispute cases&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;multiple roles(i.e., judge, plaintiff, defendant)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;fact description(판결에 대한 판사의 요약)을 expected summary로 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Result&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9O1sW/btrpLtjVDOF/NQWkhL29UlqiF0OEtBrC60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9O1sW/btrpLtjVDOF/NQWkhL29UlqiF0OEtBrC60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9O1sW/btrpLtjVDOF/NQWkhL29UlqiF0OEtBrC60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9O1sW%2FbtrpLtjVDOF%2FNQWkhL29UlqiF0OEtBrC60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;482&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ORACLE은 ROUGE score를 최대화하는 방향으로 greedy하게 추출한 것이다. 이를 upper bound로 두고 비교 가능하다. LEAD n이라는 것은 첫 n개의 문장을 추출한 것을 말한다. 즉 표에서 LEAD3는 처음 3개의 문장을 추출해 요약문을 구성한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Human evaluation&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서의 평가기준은 relevance와 fluency다. 즉, 생성된 요약문이 얼마나 원문과 유관하고 유창한지(자연스러운지)를 보는 것이다. 각 데이터셋마다 100개의 샘플을 선정하여 6명의 대학원생 평가자들이 평가를 진행했다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fkii3/btrpPwAadGj/tucfAiusTUvgll0ZjNXNH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fkii3/btrpPwAadGj/tucfAiusTUvgll0ZjNXNH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fkii3/btrpPwAadGj/tucfAiusTUvgll0ZjNXNH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFkii3%2FbtrpPwAadGj%2FtucfAiusTUvgll0ZjNXNH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;968&quot; height=&quot;535&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Ablation study&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/62syO/btrpHGKB9IM/kkBbrmz0FBwaJ652kwdixk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/62syO/btrpHGKB9IM/kkBbrmz0FBwaJ652kwdixk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/62syO/btrpHGKB9IM/kkBbrmz0FBwaJ652kwdixk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F62syO%2FbtrpHGKB9IM%2FkkBbrmz0FBwaJ652kwdixk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1242&quot; height=&quot;706&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;표를 보면 TC보다도 TG task가 모델의 전반적인 성능에 더 큰 영향을 주는 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Deep Learning Paper Review</category>
      <category>dialogue summarization</category>
      <category>nlp</category>
      <category>repsum</category>
      <category>summarization</category>
      <category>text summarization</category>
      <category>대화요약</category>
      <category>텍스트요약</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/346</guid>
      <comments>https://otugi.tistory.com/346#entry346comment</comments>
      <pubDate>Tue, 4 Jan 2022 21:15:36 +0900</pubDate>
    </item>
    <item>
      <title>[Anaconda] conda 가상환경 remove, copy, rename</title>
      <link>https://otugi.tistory.com/345</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;conda로 가상환경을 만들어 사용하다가 해당 환경의 이름을 변경해주고 싶을 때가 있다. 하지만 아쉽게도 conda 환경의 이름을 rename해주는 방법은 없다. 대신 해당 conda 환경을 clone한 뒤에 기존의 환경을 remove해주어야 한다. 아래의 커맨드를 차례로 입력해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1640927990914&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create --name new_name --clone old_name
conda remove --name old_name --all&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;new_name 부분에 새로운 가상환경 이름을, old_name 부분에 제거할 기존의 가상환경 이름을 넣어주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/AI 개발</category>
      <category>anaconda</category>
      <category>conda</category>
      <category>conda clone</category>
      <category>conda create</category>
      <category>conda remove</category>
      <category>가상환경</category>
      <category>아나콘다</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/345</guid>
      <comments>https://otugi.tistory.com/345#entry345comment</comments>
      <pubDate>Fri, 31 Dec 2021 14:21:14 +0900</pubDate>
    </item>
    <item>
      <title>[vscode] vscode ssh 암호 등록, ssh key 등록으로 비밀번호 입력 없이 접속</title>
      <link>https://otugi.tistory.com/344</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;vscode를 사용해 ssh 원격접속을 할 때 암호를 입력해주어야 한다. 이게 꽤나 불편한 게 디렉토리를 바꾸거나 할 때마다 입력해주어야 한다는 점이다....오늘은 이러한 암호 키를 등록해두어서 귀찮은 암호 입력 과정 없이 vscode 상에서 원격 서버 접속을 해 사용할 수 있는 방법을 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ssh-key 생성&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;윈도우에서 powershell에 들어가 아래의 명령어로 공개키/암호키 쌍을 만들어준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1639900109408&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh-keygen -t rsa&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;키 파일 SCP 전송&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이제 만들어 준 key 파일을 해당 서버로 전송해야 한다. 아래와 같이 명령어로 해주어도 되고, WinSCP 같은 프로그램을 사용해도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1639900264446&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;scp (id_rsa.pub경로) (아이디@호스트):id_rsa.pub&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;원격 서버에 접속해보면 id_rsa.pub 파일이 홈디렉토리에 있을 것이다. 이제 아래의 명령어를 차례로 입력해 authorized_keys에 공개키를 추가해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1639900391990&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm -rf .ssh
mkdir .ssh
chmod 700 .ssh
cat id_rsa.pub &amp;gt;&amp;gt; .ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ssh config 파일 설정&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이제 다시 vscode로 돌아와 F1을 누른 뒤 Configure SSH Host를 누르고 config 파일에 들어가 설정을 해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그리고 config 파일에서 아래와 같이 작성한 뒤 key 파일의 경로를 지정해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1639900670302&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Host TEST
    HostName 3.35.67.55
    User ec2-user
    IdentityFile (여기에 키 파일의 경로 입력)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Host 옆의 TEST는 해당 원격서버의 이름이다. vscode 상에서 이제 저 이름을 선택하면 해당 서버로 접속 가능하다. 원하는 이름으로 기억하기 쉽게 지정해도 된다. HostName은 해당 서버의 IP 주소이다. 이제 번거로운 암호 입력 없이 vscode 상에서 ssh 원격 접속을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Reference : &lt;a href=&quot;https://snwo.tistory.com/173&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://snwo.tistory.com/173&lt;/a&gt;&lt;/p&gt;</description>
      <category>리눅스</category>
      <category>ssh</category>
      <category>ssh config</category>
      <category>ssh key</category>
      <category>ssh key 생성</category>
      <category>ssh 설정</category>
      <category>vsCode</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/344</guid>
      <comments>https://otugi.tistory.com/344#entry344comment</comments>
      <pubDate>Sun, 19 Dec 2021 17:00:16 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round A Rabbit house 풀이</title>
      <link>https://otugi.tistory.com/343</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639898480963&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhqMI7/hyMJM8ZSuo/6RJpA1MuIEVhXl0mliTO30/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhqMI7/hyMJM8ZSuo/6RJpA1MuIEVhXl0mliTO30/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BFS를 사용하면 된다. 핵심은 상자가 많은 칸의 주변을 먼저 채워준다는 것이다. 이를 위해 우선순위 큐를 사용하였다. 생각해보면 상자의 갯수는 계속해서 바뀔 수 있다. arr = [2,0,4]에서 0번째 인덱스부터 탐색할 경우 1번째 인덱스의 수는 1이 될 것이다. 최소수를 구해야하므로. 그런데 다시 2번째 인덱스의 4를 보면 1번째 인덱스는 다시금 3으로 수정되어야 하는 경우가 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이같은 경우가 생기는 이유는 작은 수를 큰 수보다 먼저 탐색했기 때문이다. 따라서 우선순위 큐를 사용해 상자의 갯수가 큰 칸을 기준으로 먼저 탐색해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1639898726152&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cb14

import heapq

import copy 
D = ((1,0),(-1,0),(0,1),(0,-1))
T = int(input())
for t in range(T):
    arr = []
    r, c = map(int, input().split())
    for i in range(r):
        temp = list(map(int, input().split()))
        arr.append(temp)
    q = []
    for i in range(r):
        for j in range(c):
            if arr[i][j] != 0:
                heapq.heappush(q, (-arr[i][j], (i,j)))
    visit = [[0 for _ in range(c)] for _ in range(r)]
    result = copy.deepcopy(arr)
    while q:
        element = heapq.heappop(q)
        value, x, y = -element[0], element[1][0], element[1][1]
        if visit[x][y] != 1:
            visit[x][y] = 1
            for dx, dy in D:
                nx, ny = x+dx, y+dy
                if 0&amp;lt;=nx&amp;lt;=r-1 and 0&amp;lt;=ny&amp;lt;=c-1 and visit[nx][ny] == 0:
                    result[nx][ny] = max(result[nx][ny], value-1)
                    heapq.heappush(q, (-result[nx][ny], (nx,ny)))
    cnt = 0
    for i in range(r):
        for j in range(c):
            cnt += result[i][j] - arr[i][j]
    print(f&quot;Case #{t+1}: &quot; + str(cnt))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>BFS</category>
      <category>google coding competition</category>
      <category>google kickstart</category>
      <category>kick start</category>
      <category>rabbit house</category>
      <category>구글 킥스타트</category>
      <category>너비우선탐색</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>킥스타트</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/343</guid>
      <comments>https://otugi.tistory.com/343#entry343comment</comments>
      <pubDate>Sun, 19 Dec 2021 16:26:11 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round A L shaped plots 풀이</title>
      <link>https://otugi.tistory.com/342</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1639810317931&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OG82P/hyMKRtxopb/LLZIPxHZ9BxsYN0lpsU0W1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OG82P/hyMKRtxopb/LLZIPxHZ9BxsYN0lpsU0W1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;본 무제는 DP를 사용하는 문제이다. test set 2의 사이즈를 보면 유추할 수 있겠지만 대략 O(R*C) 시간복잡도 내에 풀어야 통과 가능하다. 그 말은 즉, matrix의 한 위치를 한 번씩만 탐색해서 답을 찾아내야 한다는 것이다. 한 번씩만 탐색하는데 가능한 경우를 찾으려면 탐색하는 순간의 (i,j)가 L shape에서 교차점이라고 생각하고 찾으면 된다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만약 (i,j) 위치를 기준으로 위로 6칸, 오른쪽으로 4칸을 연장시킬 수 있다고 해보자. 그러면 (위, 오른쪽) = (6,3), (4,2), (2, 4)의 3가지 경우가 가능하다. 문제의 조건에서 긴 쪽은 작은 쪽의 길이의 2배라고 하였으니, 일반화 시켜 위로 U, 오른쪽으로 R만큼 뻗어나갈 수 있다면 U가 긴 쪽인 경우는 max(min(U//2, R) - 1, 0)만큼, R이 긴 쪽인 경우는 max(min(R//2, U) - 1, 0)만큼이 가능하다. 1을 빼주고 0과 max를 취해주는 이유는 문제의 조건에서 짧은 쪽의 길이가 최소 2라고 하였기 때문에 만약 min(U//2, R)의 결과가 1이나 0이 나오는 경우를 제외해주기 위해서다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1639810765917&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#analysis
import copy
T = int(input())
for t in range(T):
    arr = []
    r,c = map(int, input().split())
    for i in range(r):
        temp = list(map(int, input().split()))
        arr.append(temp)
    U, D, L, R = copy.deepcopy(arr), copy.deepcopy(arr), copy.deepcopy(arr), copy.deepcopy(arr)
    for i in range(1, r):
        for j in range(c):
            if arr[i][j] == 1:
                U[i][j] += U[i-1][j]
    for i in range(r-2, -1, -1):
        for j in range(c):
            if arr[i][j] == 1:
                D[i][j] += D[i+1][j]
    for i in range(r):
        for j in range(1,c):
            if arr[i][j] == 1:
                L[i][j] += L[i][j-1]
    for i in range(r):
        for j in range(c-2, -1, -1):
            if arr[i][j] == 1:
                R[i][j] += R[i][j+1]
    ans = 0
    for i in range(r):
        for j in range(c):
            ans += max(min(U[i][j]//2, R[i][j])-1, 0)
            ans += max(min(U[i][j]//2, L[i][j])-1, 0)
            ans += max(min(D[i][j]//2, R[i][j])-1, 0)
            ans += max(min(D[i][j]//2, L[i][j])-1, 0)
            ans += max(min(R[i][j]//2, D[i][j])-1, 0)
            ans += max(min(R[i][j]//2, U[i][j])-1, 0)
            ans += max(min(L[i][j]//2, D[i][j])-1, 0)
            ans += max(min(L[i][j]//2, U[i][j])-1, 0)
    print(f&quot;Case #{t+1}: &quot; + str(ans))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>dp</category>
      <category>google coding competition</category>
      <category>google kickstart</category>
      <category>kickstart</category>
      <category>구글 알고리즘</category>
      <category>구글 킥스타트</category>
      <category>알고리즘</category>
      <category>코딩 대회</category>
      <category>킥스타트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/342</guid>
      <comments>https://otugi.tistory.com/342#entry342comment</comments>
      <pubDate>Sat, 18 Dec 2021 16:00:05 +0900</pubDate>
    </item>
    <item>
      <title>WISENUT 2021 AI 텍스트 요약 온라인 해커톤 참가 후기</title>
      <link>https://otugi.tistory.com/341</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;대회 개요&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;11월 19일 ~ 12월 3일까지 열린 WISENUT이 주최한 2021 AI 텍스트 요약 해커톤에 참가했다. 해당 대회는 온라인으로 이루어졌는데 AI factory(&lt;a href=&quot;http://aifactory.space/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://aifactory.space/&lt;/a&gt;)측에서 운영을 담당하여 해당 사이트를 통해 참가 접수가 가능했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;간단히 말하면 주어진 데이터셋을 가지고 모델을 학습 시켜 텍스트 요약 성능을 겨루는 대회였다. 데이터는 소설, 문화, 뉴스, 브리핑, 드라마, 역사 텍스트로 이루어져 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;제출한 요약문의 성능은 Rouge-L F1 score의 평균 값으로 채점되었다. 쉽게 말하면 핵심적인 내용들은 담겨 있으면서도 원문의 내용과 긴 시퀀스로 겹치는 부분이 많은 요약문을 생성해내는 것이 관건이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1차 시도&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우선 주어진 학습 데이터를 살펴보았다. 데이터는 orginal 원문과 summary 요약문의 여러 쌍으로 이루어져 있었다. 여기서 나는 summary가 어떻게 이루어져 있는지를 살펴보면 좀 더 높은 점수를 받는데 도움이 될 거라 생각했다. 대부분의 경우가 그렇지만 사실상 데이터로부터 해답을 얻어낼 수 있는 경우가 많다. 특히나, 단기적인 시점에서의 극한의 성능향상을 요구하는 경진대회 같은 경우는 더더욱.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터를 잘 살펴보니 2~3문장의 요약으로 이루어져 있었고, 각 문장들은 원문에 있는 문장과 동일하였다. 이를 통해 나는&amp;nbsp;추출 요약(Extractive summary) 방식으로 하는 것이 생성 요약(Abstractive summary) 방식보다 높은 스코어를 얻기에 유리하다고 판단했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나는 &lt;u&gt;사전훈련된 임베딩&lt;/u&gt;을 사용하고자 했었다. 선택했던 것이 가자 최신 버전의 한국어 GloVe였다. 임베딩을 한 뒤 text rank 알고리즘을 사용해 추출 요약을 생성하려고 했었다. 데이터 전처리도 하고 여차저차 복잡한 과정을 거치고 나니 문득 생각이 든 것이, &quot;과연 대회에서 주어진 데이터셋 내의 단어들에 대한 임베딩 벡터가 GloVe에 잘 반영이 되어있을까?&quot; 였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;뉴스기사나 브리핑과 같은 경우 최신 데이터들도 많았는데 거기엔 '코로나'라는 단어가 많이 등장하였고, 이와 유관한 '질병청', '화이자', '모더나' 등의 단어들도 많았다. 바로 GloVe 임베딩 파일에서 서치를 해보니 해당 단어들에 대한 벡터 변환 정보가 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;선택지는 이제 두 가지가 되는데, 직접 임베딩을 만들어 사용할 것인가 아니면 사전 훈련된 모델을 사용해 생성요약 방법을 시도해볼 것인가였다. 남은 시간이 많지 않았기에 나는 두번째 방법을 택했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; font-family: 'Noto Serif KR';&quot;&gt;2차 시도&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;내가 사용한 사전 훈련된 모델은 SKT에서 발표한 한국어 BART 모델 &lt;u&gt;KoBART&lt;/u&gt;였다.(좋은 모델을 공개로 풀어준 SKT에게 감사하다 ㅎㅎ. 모델을 비공개로 해두는 기업들도 생각보다 많다.) 해당 모델의 구체적인 사용법은 &lt;a href=&quot;http://blog.ju-ing.com/posts/KoBART-summarization/#demo&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ju-ing's Blog&lt;/a&gt;를 참고하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나의 계획은 이미 사전 훈련된 KoBART 모델에 대회에서 주어진 데이터셋을 활용해 Fine-tuning을 시키자는 것이었다. Fine-tuning을 통해 전체 layer를 모두 훈련시킬 필요가 없어 조금 더 학습 시간을 절약할 수 있을거라고 생각했기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터 전처리가 우선 선행되었어야 했는데....하... 여기서 애를 많이 먹었다. 항상 느끼는 거지만 요즘은 대부분 사전 훈련된 모델들이 많고 이들을 많이 사용하기 때문에 사실상 많은 시간을 할애하게 되는 부분이 데이터 전처리인 것 같다. 더구나 한국어는 영어에 비해 전처리가 많이 복잡하다...Pandas에서 무수한 에러가....&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어쨋거나 우여곡절 끝에 학습을 시켜서 요약문 결과를 생성해냈다. 여기까지 했을 때가 마감을 1시간 정도 남겨두었을 시점이었다 ㅋㅋㅋㅋ 채점을 위해 데이터를 대회에서 요구하는 양식으로 정리도 해서 제출해야 했기 때문에 마음이 급했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하이퍼 파라미터 튜닝이나 다른 기법들을 시도해보고 싶었는데 시간이 없었다. ㅜㅜㅜ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;결과&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어찌되었든 부랴부랴 마감을 해서 제출을 했고 점수를 보니 41점 정도가 나왔다. 제출 당시 리더보드의 1등 성적이 53점이었다. 점수 차이가 약 12점 정도였다. fine tuning만을 마쳤는데 이 정도 차이면 하이퍼 파라미터 튜닝이라던가 구조적인 측면에서의 다른 변화를 주어 재학습을 시키면 분명 성능을 더 올릴 수 있었을 것 같은데 아쉬웠다. 그렇게 50여명이 참가한 대회에서 나는 8등의 성적으로 마쳤다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvqf28/btrnEKfSliq/wZb8eGKWfIV5eXc1Wk8vP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvqf28/btrnEKfSliq/wZb8eGKWfIV5eXc1Wk8vP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvqf28/btrnEKfSliq/wZb8eGKWfIV5eXc1Wk8vP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcvqf28%2FbtrnEKfSliq%2FwZb8eGKWfIV5eXc1Wk8vP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1152&quot; height=&quot;648&quot; data-filename=&quot;제목 없음.png&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;대회를 마치며&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;금번 대회 참가는 재미있는 경험이었다. 우선, 내가 해오던 대부분의 실습이나 NLP 분야의 다른 대회들이 주로 영어를 대상으로 하는 반면 본 대회는 한국어 데이터셋을 대상으로 했다. 그래서 뭔가 결과를 보면서도 더 재미있게 구현했던 것 같다. (사실 영어 긴 문장 요약하는 것도 해봤는데 막상 결과 보면 이게 요약이 잘 된건지 Human evaluation으로 평가해보기 힘들다 ㅋㅋㅋㅋ 영어 긴 글 보고 원문 잘 요약했는지 빨리 빨리 평가하기가 어려우니까....) 방학 기간을 통해서 NLP 분야 다른 대회들도 나가봐야징~ ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Contest</category>
      <category>AI factory</category>
      <category>AI 모델</category>
      <category>KoBART</category>
      <category>nlp</category>
      <category>text summarization</category>
      <category>경진 대회</category>
      <category>생성 요약</category>
      <category>와이즈넛</category>
      <category>추출 요약</category>
      <category>텍스트 요약</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/341</guid>
      <comments>https://otugi.tistory.com/341#entry341comment</comments>
      <pubDate>Sat, 11 Dec 2021 19:46:46 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round G Staying Hydrated 풀이</title>
      <link>https://otugi.tistory.com/340</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1638963054094&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/7wH9K/hyMC6sy1Ut/kKdhkmh35MYItPlP3Es72K/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/7wH9K/hyMC6sy1Ut/kKdhkmh35MYItPlP3Es72K/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단순히 brute-force 방식으로 풀면 시간 초과 에러가 난다. 이 문제에서 핵심은 search를 어떻게 효율적으로 할 것인가이다. 이를 위해선 최적의 x, y 좌표가 어디에 위치할 것인지에 대해 생각해봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;x의 최적 위치만을 찾는다고 생각해보자. 만약 x1이라는 특정 지점을 기준으로 좌측에 가구가 a개 우측에 가구가 b개 있다고 해보자. 만약 a&amp;gt;b라면 각 가구로부터 거리가 최소가 되기 위한 x의 좌표는 당연히 x1을 기준으로 조금 더 좌측에 치우친 방향에 존재할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이러한 생각을 가지고 x와 y의 좌표를 모두 구하면 된다. 두 개를 한꺼번에 구하려 하지 말고 따로 나누어 구한다고 생각해야 한다. 최종 시간 복잡도는 O(nlogn)이 나오게 된다.(정렬하는 부분 때문에)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1638963044024&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/00000000004362d6/00000000008b3a1c

T = int(input())
for t in range(T):
    k = int(input())
    x, y = {}, {}
    for i in range(k):
        x1, y1, x2, y2 = list(map(int, input().split()))
        if x1 in x:
            x[x1] += 1
        else:
            x[x1] = 1
        if x2 in x:
            x[x2] += 1
        else:
            x[x2] = 1
        if y1 in y:
            y[y1] += 1
        else:
            y[y1] = 1
        if y2 in y:
            y[y2] += 1
        else:
            y[y2] = 1

    x = sorted(x.items())    
    y = sorted(y.items())
    
    ans_x, ans_y = 0, 0

    count = -1 * k
    for i in range(len(x)):
        count += x[i][1]
        if count &amp;gt;= 0:
            ans_x = x[i][0]
            break
    count = -1 * k
    for i in range(len(y)):
        count += y[i][1]
        if count &amp;gt;= 0:
            ans_y = y[i][0]
            break

    print(f&quot;Case #{t+1}: &quot;+str(ans_x)+' '+str(ans_y))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>google coding competition</category>
      <category>google kickstart</category>
      <category>kickstart</category>
      <category>PYTHON</category>
      <category>staying hydrated</category>
      <category>구글 킥스타트</category>
      <category>알고리즘</category>
      <category>코딩 테스트</category>
      <category>킥스타트</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/340</guid>
      <comments>https://otugi.tistory.com/340#entry340comment</comments>
      <pubDate>Wed, 8 Dec 2021 20:35:22 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round H Painter 풀이</title>
      <link>https://otugi.tistory.com/339</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88#problem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88#problem&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1638018789199&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88#problem&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88#problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bnxwyc/hyMuEC06Qf/ETDUDyXkc43pKqcLBXZ7Ak/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88#problem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88#problem&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bnxwyc/hyMuEC06Qf/ETDUDyXkc43pKqcLBXZ7Ak/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;문제가 조금 복잡하지만 구현 자체는 생각보다 단순하다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1638018853546&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;d = {'R':['R'], 'B':['B'], 'Y':['Y'], 'O':['R', 'Y'], 'P':['R', 'B'], 'G':['Y', 'B'], 'A':['R', 'Y', 'B'], 'U':[]}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 같이 각 컬러마다 필요한 원소색깔을 담은 딕셔너리를 만들어 둔다. 이 문제의 핵심은 결국 몇 번의 붓질로 모두 다 칠할 수 있는지 그 최소 횟수를 구하는 것이다. 만약 주어진 데이터가 YYBBGG라면 이를 원소색으로 분리하면&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Y&amp;nbsp; &amp;nbsp;Y&amp;nbsp; &amp;nbsp;B&amp;nbsp; &amp;nbsp;B&amp;nbsp; &amp;nbsp;Y,B&amp;nbsp; &amp;nbsp;Y,B&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 같이 된다. 여기서 원소색인 Y와 B를 따로 분류해내서 아래와 같이 별도의 리스트로 만든 뒤, 해당 인덱스 자리에 해당 원소색이 있으면 1로 만들어준다. 위의 예시는 아래와 같이 나타낼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Y_list = [1, 1, 0, 0, 1, 1]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;B_list = [0, 0, 1, 1, 1, 1]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3번째, 4번째 자리에는 Y가 필요없기 때문에 0이 된다. 결국 칠해주어야 하는 색은 3원색들이기 때문에 위와 같은 리스트에서 연속된 1의 갯수를 카운트 해주면 답이 된다. Y_list와 B_list에서 연속된 1의 갯수는 각각 2개, 1개이다. 따라서 답은 2+1=3이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;시간복잡도는 O(n)이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1638018803116&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008d9a88

import copy

d = {'R':['R'], 'B':['B'], 'Y':['Y'], 'O':['R', 'Y'], 'P':['R', 'B'], 'G':['Y', 'B'], 'A':['R', 'Y', 'B'], 'U':[]}
T = int(input())
for t in range(T):
    n = int(input())
    s = input()
    job = []
    for i in range(n):
        job.append(copy.deepcopy(d[s[i]]))
    cnt = 0
    R_list, B_list, Y_list = [0]*n, [0]*n, [0]*n
    for i in range(len(job)):
        if 'R' in job[i]:
            R_list[i] = 1
        if 'B' in job[i]:
            B_list[i] = 1
        if 'Y' in job[i]:
            Y_list[i] = 1
    if R_list[0] == 1:
        cnt += 1
    for i in range(1,n):
        if R_list[i-1]==0 and R_list[i]==1:
            cnt += 1
    if B_list[0] == 1:
        cnt += 1
    for i in range(1,n):
        if B_list[i-1]==0 and B_list[i]==1:
            cnt += 1 
    if Y_list[0] == 1:
        cnt += 1
    for i in range(1,n):
        if Y_list[i-1]==0 and Y_list[i]==1:
            cnt += 1
    print(f'Case #{t+1}: '+str(cnt))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>google coding competition</category>
      <category>google kick start</category>
      <category>kick start</category>
      <category>painter</category>
      <category>PYTHON</category>
      <category>round H</category>
      <category>구글 킥스타트</category>
      <category>알고리즘</category>
      <category>코딩 테스트</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/339</guid>
      <comments>https://otugi.tistory.com/339#entry339comment</comments>
      <pubDate>Sat, 27 Nov 2021 22:20:07 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 파이썬 가비지 콜렉터란?(Garbage Collector; GC)</title>
      <link>https://otugi.tistory.com/338</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프로그래밍 언어는 메모리 관리를 어떻게 할까?&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프로그래밍 언어는 메모리 관리를 어떻게 하는 것일까? C나 C++ 같은 저수준의 언어는 malloc(), free()와 같이 메모리를 직접적으로 관리하는 함수들을 사용해 메모리 할당과 해제를 한다. 그런데 python, JS, C# 등의 언어를 사용할 때를 생각해보면 개발을 하는 우리는 &quot;메모리&quot;에 대해 생각하지 않고 코드를 짠다. 현대적인 언어로 오면서 메모리 관리는 점차 사람이 하지 않는 쪽으로 바뀌었다. 하지만 분명히 메모리가 어떠한 방식으로든 할당이 되어야 할 것이고, 이를 사람이 신경쓰지 않는다면 누군가가 대신해 주고 있다는 뜻이다. 특히, 파이썬에서 이를 해주는 것이 바로 &lt;b&gt;가비지 콜렉터(Garbage Collector, 줄여서 GC)&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메모리를 직접 관리해주면?&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아까 서두에서 C, C++ 같은 언어가 메모리를 개발자가 직접 할당, 해제해준다고 말했다. 그럼 이러한 경우 어떠한 단점이 있어서 점차 메모리를 신경쓰지 않아도 되는 언어들로의 발전이 이루어진걸까? 메모리를 사람이 직접 관리하면 아래와 같은 문제점들이 생길 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 필요없는(사용하지 않는) 메모리를 해제해주지 않으면 &lt;b&gt;memory leak&lt;/b&gt;이 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 사용 중이던 메모리를 해제해버리면 &lt;b&gt;프로그램이 중단&lt;/b&gt;되고, &lt;b&gt;데이터가 손실&lt;/b&gt;될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;때문에 점차 이러한 메모리 관리를 언어 그 자체에게 맡기는 방향으로의 발전이 이루어진 것이다. 하지만 이것이 단점만 있는 것은 아니다. 사람이 직접 개입하면 좀 더 훌륭하게 메모리 최적화를 할 수 있고, micro managing이 가능하다. 이러한 optimization이 중요한 분야가 따로 있다. 우주항공 분야의 프로그램들이 특히 그러하다. (대부분 Jop Posting을 보아도 C나 C++ 같은 언어는 특정하게 뽑는 분야가 정해져있다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;또한 개발자의 개인적인 차원에선 이러한 언어들을 한 번쯤 배워두고 사용해보는 것이 굉장히 좋은 경험이 되는 것 같기도 하다. 이것은 내 개인적인 생각이지만! 나는 C, C++을 가장 처음으로 배웠고, 그 다음으로 Python을 사용하였다. 그런데 C를 배우고나서 python을 배울때는 생각보다 습득이 빠르고 쉬웠다. 거꾸로 생각해보니 C는 python보다 배우기가 어려웠던 것 같다. 그 이유가 바로 메모리를 사람이 모두 관리해주기 때문이다. 하지만 그러한 C를 배웠을 때 생각했던 메모리를 어떻게 할당해줄지에 대한 사고 방식이 분명 도움이 되었다.(생각보다 python 같은 언어를 사용하면 메모리에 대해 생각하면서 코드를 짜볼 기회가 정말 거의 없다, index range 벗어나고 이런거 말고)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;파이썬의 GC&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Cpython에서 주로 사용하는 메모리 관리법은 &lt;b&gt;레퍼런스 카운팅(Reference Counting)&lt;/b&gt;이다. 쉽게 말해 우리가 객체를 만들 때 그것이 얼마나 자주 사용되는지 카운트하는 것이다. 캐시 메모리의 교체 방식에서 LRU(Least Recently Used)가 참조 횟수를 카운트해서 victim을 고르는 것과 비슷하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;즉, 파이썬은 우리가 객체를 생성해서 사용할 때마다 해당 객체의 reference count를 1씩 증가시키고, 해제할 때 1씩 감소시킨다. 이것이 0이 되면 객체의 메모리 할당이 해제된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GC와 프로그램의 성능&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GC는 프로그램의 성능에 영향을 미친다. 가비지 컬렉션을 수행하려면 프로그램을 완전히 중지해야 한다. 따라서 객체가 많을수록 가비지를 컬렉션하기 위해 더 많은 시간이 필요하다. 가비지 컬렉션 주기가 짧다면 여유 메모리를 확보할 순 있지만 프로그램이 중단되는 상황이 많이 발생한다. 반대로 주기가 길다면 프로그램이 자주 중단되지는 않지만 메모리 공간에 가비지가 많이 쌓이게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/파이썬</category>
      <category>garbage collection</category>
      <category>Garbage Collector</category>
      <category>gc</category>
      <category>PYTHON</category>
      <category>가비지 컬렉션</category>
      <category>가비지 컬렉터</category>
      <category>가비지 콜렉션</category>
      <category>파이썬</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/338</guid>
      <comments>https://otugi.tistory.com/338#entry338comment</comments>
      <pubDate>Sat, 20 Nov 2021 15:47:57 +0900</pubDate>
    </item>
    <item>
      <title>[Google Kick Start] 2021 구글 킥스타트 Round H Transform the string 풀이</title>
      <link>https://otugi.tistory.com/337</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1637385125202&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kick Start - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Jqe8x/hyMpeKW8XQ/f9DpQd5lfmdOEmseyugUHk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Jqe8x/hyMpeKW8XQ/f9DpQd5lfmdOEmseyugUHk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kick Start - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hone your coding skills with algorithmic puzzles meant for students and those new to coding competitions. Participate in one round or join them all.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나의 풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;단순한 구현 문제이다. 우선 F를 set으로 바꿔주어야 한다. 어차피 우리가 필요한 것은 S에 F의 글자가 있는지만 확인하면 되니까 중복글자를 제거해줘도 된다. 그런 뒤 S를 순차적으로 탐색하면서 S[i]가 F에 있는지 살펴보고 F의 각 글자들마다 proceeding, following으로 취급했을 때의 거리를 계산해 minimum 값을 취해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;근데 다 풀고나니 사실 이보다 시간복잡도를 더 줄일 수도 있을 것 같다. 만약 S에서도 중복되는 글자들이 있으면 그것들을 이전에 구한 값으로 답에 더해주면 되니까. 대신 메모리를 더 쓰게 된다. 어쨌거나 아래 풀이로도 제출하니 통과가 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1637385151816&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435914/00000000008da461

def min_op(a, b):
    a, b = ord(a), ord(b)
    return min(abs(a-b), min(a,b)+26-max(a,b))

T = int(input())
for t in range(T):
    op_num = 0
    s = input()
    f = set(list(input()))
    for i in range(len(s)):
        if s[i] not in f:
            min_path = 26
            for f_alpha in f:
                min_path = min(min_path, min_op(s[i], f_alpha))
            op_num += min_path
    print(f&quot;Case #{t+1}: &quot;+str(op_num))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/Google Kick Start</category>
      <category>google coding competition</category>
      <category>google kick start</category>
      <category>kick start</category>
      <category>transform the string</category>
      <category>구글 코딩 컴페티션</category>
      <category>구글 킥스타트</category>
      <category>알고리즘</category>
      <category>코딩 테스트</category>
      <category>킥스타트</category>
      <author>땅어</author>
      <guid isPermaLink="true">https://otugi.tistory.com/337</guid>
      <comments>https://otugi.tistory.com/337#entry337comment</comments>
      <pubDate>Sat, 20 Nov 2021 14:15:48 +0900</pubDate>
    </item>
  </channel>
</rss>