<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tree_jhk.log</title>
        <link>https://velog.io/</link>
        <description>LinkedIn: https://www.linkedin.com/in/junhyuk-kwon-8578b5247/      (1촌 환영해요) (블로그 글은 나중에 시간되면 회고 쓰는걸로....)</description>
        <lastBuildDate>Fri, 31 Mar 2023 10:28:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>tree_jhk.log</title>
            <url>https://velog.velcdn.com/images/tree_jhk/profile/496bf2af-1468-41cf-b760-2c699584ed99/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. tree_jhk.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tree_jhk" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[네이버 부스트캠프 AI Tech 4기 후기]]></title>
            <link>https://velog.io/@tree_jhk/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%94%84-AI-Tech-4%EA%B8%B0-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%94%84-AI-Tech-4%EA%B8%B0-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Fri, 31 Mar 2023 10:28:59 GMT</pubDate>
            <description><![CDATA[<p>부스트캠프 4기 RecSys(추천시스템) 트랙을 수료를 했기에 후기를 작성하네요!</p>
<p>2022년 9월~2023년 2월 5개월 동안의 교육이 진행됐습니다!</p>
<p>회고는 미루고 미루다가 드디어 쓰게 됐네요...</p>
<p>개인적인 생각이 담긴 것을 참고해서 봐주시길 바랍니다!</p>
<h1 id="내-이야기">내 이야기</h1>
<h3 id="부스트캠프를-신청한-계기">부스트캠프를 신청한 계기</h3>
<ul>
<li><p>외적인 동기:
교내 학부연구생으로 AI를 공부하고 프로젝트를 진행하면서, AI 분야로 진로를 잡기로 마음을 먹게 됐습니다. 그런데 전기공학과와 컴퓨터공학과는 거리가 멀어서 진로를 아예 변경해야 해서 고민이 많았습니다.
그러다가 에브리타임에서 전기과에서 컴퓨터공학으로 진로를 잡는 것에 대한 고민글을 올렸고 같은 과인데 ML직무로 취업한 선배님을 만나게 됐습니다.</p>
<img src="https://velog.velcdn.com/images/tree_jhk/post/9f2d6388-0e4a-405f-a655-7c9e17ef6a53/image.png" width="100%" height="50%">
이 선배님은 네이버 부스트캠프 1기를 수료하고 N사에 취직하셨다고 말씀하셨습니다. 해당 과정이 도움이 많이 됐다고 해서 저도 부스트캠프를 지원해야겠다고 1월부터 마음 먹고 코딩테스트를 공부해나갔습니다.
</li>
<li><p>내적인 동기:</p>
<ol>
<li><p>비전공자이기 때문에 휴학을 해서라도 AI에 대해 집중적으로 공부를 하고 싶었습니다. (특히, 모델링 실력을 키우고 싶었습니다.)</p>
</li>
<li><p>개인적으로 AI 교육 부트캠프 중 가장 유명하고 인기가 많기 때문에 양질의 교육을 받을 수 있다고 생각했습니다.</p>
</li>
<li><p>부트캠프이지만, 서류전형과 2회의 코딩테스트를 통과해야 하기 때문에 좋은 동료들을 만날 수 있다고 생각했습니다.</p>
</li>
</ol>
</li>
</ul>
<h3 id="부스트캠프-recsys-트랙-선택-이유">부스트캠프 RecSys 트랙 선택 이유</h3>
<p>부스트캠프에서는 CV, NLP, RecSys 세 가지 트랙 중 하나를 선택하게 됩니다. 사실 저는 이전에 CV 분야 프로젝트를 진행했어가지고 CV를 생각하고 있었습니다.</p>
<p>그런데,</p>
<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/bf040913-bb5b-4305-86cf-28d3b86c089d/image.png" alt="text" width="50%" height="30%">
</p>

<p>중간에 <a href="https://velog.io/@tree_jhk/CLOVA-AI-RUSH-CONFERENCE-2022">추천시스템 대회</a>를 진행하면서 RecSys에 흥미가 생겨가지고 RecSys로 트랙을 변경했습니다. 현재는 추천시스템 분야의 연구실에서 학부연구생 활동을 하고 있습니다.</p>
<h3 id="부스트캠프에서-다루는-내용">부스트캠프에서 다루는 내용</h3>
<ul>
<li>과정 초반: AI 기초(수학, 파이썬, AI이론)</li>
<li>과정 중반: 트랙별 기초 + 트랙별 대회 3개 + MLOps</li>
<li>과정 후반: 트랙별 프로젝트(자유 주제 or 기업 연계 주제)<p align='center'>
<img src="https://velog.velcdn.com/images/tree_jhk/post/0c9068a9-fca4-4efc-99b3-4c1eb98f69f8/image.png" alt="text" width="50%" height="30%">
부스트캠프 최종 프로젝트입니다.
</p> 

</li>
</ul>
<p><a href="https://github.com/boostcampaitech4lv23recsys2/final-project-level3-recsys-12">저희 팀 프로젝트 GitHub (많관부)</a>
<a href="https://github.com/boostcampaitech4lv23recsys2/level2_dkt_recsys-level2-recsys-12">부스트캠프 대회 중 제일 재밌게 했던 대회 - DKT GitHub</a></p>
<p>과정 진행하면서 중간에, 취업 관련 여러 꿀특강들부터 마음 다스리기 특강들까지 다양한 특강들과 이벤트들이 기다리고 있습니다 ㅎㅎ
빡세긴하지만 동시에 재밌어요!!</p>
<h3 id="부스트캠프-수료-후-나한테-남게-된-것들">부스트캠프 수료 후 나한테 남게 된 것들</h3>
<ul>
<li>든든한 포트폴리오(대회들, 프로젝트)</li>
<li>AI 지식과 코딩력</li>
<li>사람 좋고 실력 좋은 동료들 (지금도 자주 연락합니다 ㅎㅎ)</li>
<li>든든한 현직자 멘토님들</li>
<li>취업 연계도 여러 개 있는데, 졸업까지 3학기가 남아서 저는 제외 대상입니다 ㅋㅋ <del>(내부 전형으로 네이버 인턴 기회도 있었는데 채용 과정 중에 불합격해서 뼈가 아픕니다...)</del> 관련해서는 뒤에 QnA 2번에서 더 자세히 말씀드릴게요!!</li>
</ul>
<p>저 개인적으로 남은게 많았습니다!</p>
<p>부스트캠프 과정을 소화하기 위해 제가 했던 노력들입니다:</p>
<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/92d2e3c0-abec-4bb0-9a1f-e3988625b5fb/image.png" alt="text" width="40%" height="10%">
</p> 

<ol>
<li><p>적극적으로 동료들에게 다가가고 소통을 많이하려고 했습니다!</p>
</li>
<li><p>멘토님들한테는 질문을 많이 드렸습니다!</p>
</li>
<li><p>부스트캠프 중의 강의들과 특강들 모두 최대한 기록하고 정리하려고 노력했습니다. 이는 최하단의 링크를 참조해주세요!</p>
</li>
<li><p>포트폴리오에 어필하고 싶은 부분들을 사전에 염두를 한 채로, 대회나 프로젝트를 진행할 때 그 부분들을 신경썼습니다.</p>
</li>
</ol>
<p>즉, 각자 생각하는 진로의 방향성이 있을텐데, 그 부분을 염두하면서 대회와 프로젝트를 진행하시는게 좋습니다!
<em>(예를 들어서, MLOps가 더 관심이 가면 대회 중에는 MLOps 스터디를 모집하고 프로젝트 때 MLOps 부분을 담당하는 것처럼요! 
저는 ML엔지니어가 관심이 있었고 특히 데이터를 잘 reprsentation할 수 있는 모델링에 관심이 많아서 그 방향의 실력을 키우는데에 더 집중했습니다.)</em></p>
<p><strong>부스트캠프 관련해서 기분 좋았던 적</strong> <del>(별거 아니라서 약간 민망함)</del>
부스트캠프 수료 이후, 프로젝트 관련 Recommender System KR 오픈채팅방에서 트러블슈팅 관련 칭찬 받았습니다 ㅋㅋ </p>
<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/6c170da3-6e80-4a1e-aeb2-594f5ecc90ed/image.png" alt="text" width="60%" height="10%">
  당시 칭찬 받은 내용
</p> 

<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/7f9ec83b-efd7-4028-a2fe-91e171507624/image.png" alt="text" width="70%" height="10%">
  Recommender System KR 오픈채팅 칭찬
</p> 

<p>자료에 대해 자세히 알고 싶으시면 <a href="https://dear-queen-578.notion.site/Final-Project-Wrap-Up-Report-99d475442c304775804d41523113e385">나만의집 프로젝트 Wrap Up report</a>를 확인해주세요 ㅎㅎ</p>
<p>별 것도 아니라서 부끄럽긴한데 스스로 부스트캠프 추천시스템 과정을 제대로 수료했다는 느낌을 받았던 부분이라 공유했습니다 ㅎㅎ; 
(많은 분들 앞에서 실명으로 칭찬 받아서 당시에 매우 뿌듯했습니다 ㅋㅋ)</p>
<h1 id="qna">QnA</h1>
<h3 id="1-부스트캠프에-들어오기-전에-갖추면-좋을-역량">1. 부스트캠프에 들어오기 전에 갖추면 좋을 역량</h3>
<ul>
<li><p>코딩 실력은 코딩테스트 통과할 정도면 됩니다.</p>
</li>
<li><p>Pre-course의 AI 부분 더 공부해오면 따라가는데 더 수월합니다.</p>
</li>
<li><p>웹개발, MLOps 역량을 기르는 것이 좋아보입니다. (저는 그냥 ML만 알고 갔는데 다행히도 팀원들이 웹개발을 잘해줘서 AI 위주로 프로젝트 진행했습니다.)</p>
<ul>
<li>부스트캠프 마지막 과정은 &#39;프로젝트&#39;인데, 이때 모델링 말고도 웹개발, MLOps 등등 할 것들이 많을 것입니다. </li>
<li>근데 개인적으로 웹개발 or MLOps or 경량화 중 아무거나 하나를 부스트캠프 들어오기 전에 조금 공부해보시면 나중에 큰 도움이 되실 겁니다.</li>
</ul>
</li>
<li><p>좋은 성격(?) (팀 프로젝트를 많이 하다보니 갈등 상황이나 의견 충돌을 부드럽게 대처할 줄 알아야겠습니다!)</p>
<h3 id="2-취업에-도움이-될-수-있을지">2. 취업에 도움이 될 수 있을지?</h3>
<p align='center'>
<img src="https://velog.velcdn.com/images/tree_jhk/post/68c23d86-603b-43c8-b501-2ddd75fb1fb7/image.png" alt="text" width="60%" height="50%">
네이버 인턴 불합격해서 참 속상했다...
</p>
보시다시피 내부 전형이 존재합니다. 내부 전형인만큼, 공개 모집하는 인턴이나 정규직보다 경쟁률이 낮다는 장점이 있습니다.

</li>
</ul>
<p>저 같은 경우는 취업에 대한 직접적인 도움을 받기 위해 부스트캠프를 신청한 것은 아니고, 비전공자인데 실력 키우기 위해서 온 케이스입니다.</p>
<p>그래서 여러 기업들이 있었지만 네이버 하나만 집중하고 나머지 좋은 기업들의 채용 과정을 진행하지 않았습니다.</p>
<p>주변 동료들은 업스테이지, 네이버, 연봉 5000대 스타트업 등에 합격해서 행복한 회사 생활하고 있습니다 ㅎㅎ</p>
<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/7b1ff799-52bc-45c3-93e3-df562859e1fa/image.png" alt="text" width="40%" height="50%">
</p>

<p><em><strong>그러나, 부스트캠프를 통해서 &#39;취업 연계&#39;만을 노리겠다 하는 생각은 과감하게 접길 바랍니다</strong></em>.</p>
<p>왜냐면 취업 연계를 부스트캠프 수료생 모두가 할 수는 없기 때문입니다.</p>
<p>따라서, 개인적인 생각으로는 각자 <em><strong>희망하는 기업의 공채에 합격할 수 있는 &#39;포트폴리오&#39;를 만든다는 관점으로 접근하는 것이 좋을 것 같습니다.</strong></em></p>
<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/aede4a2a-6f16-445c-9b61-09cfc38953f7/image.png" alt="text" width="60%" height="50%">
</p>
여러 회사에서 대규모 공채를 진행하니 같이 병행해야죠 ㅎㅎ


<h3 id="3-연령대가-어떻게-되고-어떤-시기에-들어오는게-좋을지">3. 연령대가 어떻게 되고, 어떤 시기에 들어오는게 좋을지?</h3>
<ul>
<li>보통 대학교 3학년~졸업생이 많습니다.</li>
<li>석사 졸업하신 분들도 있습니다.</li>
<li>직장 다니다가 오신 분들도 있습니다.</li>
<li>개발에 있어서 완전 고인물인 분도 계셨습니다.</li>
</ul>
<p align='center'>
  <img src="https://velog.velcdn.com/images/tree_jhk/post/a7727438-9b26-43a7-976f-3c72299126bc/image.png" alt="text" width="30%" height="50%">
</p>

<p>개인적으로는 시기 상관없이 빨리 올수록 좋다고 생각합니다.
왜냐면 빨리 올수록 다음에 뭘 공부하거나 어떻게 공부할지 감이 오기 때문입니다.</p>
<h3 id="4-온라인오프라인-관련학업-병행-관련">4. 온라인/오프라인 관련(학업 병행 관련)</h3>
<p>우선적으로 말씀 드릴 것은, 학업 병행은 웹강만 있는 상황이 아니면 거의 불가능하고 지방에 사셔도 충분히 과정을 진행하는 데에 있어서 큰 문제가 없다는 것입니다.</p>
<p>이외에도,</p>
<ul>
<li>진행되는 강의나 특강은 모두 100% 온라인입니다.</li>
<li>종종 부스트캠프 내에서 오프라인 시간을 가져서 사람들끼리 대면으로 볼 수 있게 하는 시간이 있는데요.
필참은 아니라서 부담 가질 필요 전혀 없습니다.</li>
<li>프로젝트 진행할 때는 대면으로 만나면서 더 친해지고 효율적으로 작업할 수 있기 때문에 아무래도 수도권에 사는게 여건상 더 좋기는 합니다.</li>
</ul>
<p>부스트캠프를 진행하면서 팀이 2번 바뀌는데, 두 팀 내의 팀원들 모두 수도권에 살기 때문에 대면으로 여러 번 만나서 작업했습니다. 덕분에 더 친해질 수 있게 됐습니다.</p>
<h3 id="5-부스트캠프-들으면-취업하는지">5. 부스트캠프 들으면 취업하는지?</h3>
<p>어떤 부트캠프여도 부트캠프 수강만으로는 취업하기 어렵습니다...
어떤 부트캠프여도 부트캠프 내에서 각자가 어떻게 생활하는지에 따라 포트폴리오의 질이 좋을 것이고 그러면 자연스럽게 취업에 도움이 되죠.</p>
<p><em>엥 그러면 부스트캠프의 메리트는 없는건가?!</em></p>
<ul>
<li><p>아니요! 위에서 설명한 내용들은 거짓이나 과장 하나 없이 쓴 거고 정말 큰 도움 됩니다.</p>
</li>
<li><p>그리고 실력이 전과 후가 많이 차이가 나기 때문에 수강하면 정말 좋습니다.</p>
<h3 id="6-그래서-추천하는지">6. 그래서 추천하는지?</h3>
<p align='center'>
<img src="https://velog.velcdn.com/images/tree_jhk/post/b1f5fad5-0361-4c03-b7f0-f80ba54dce8f/image.png" alt="text" width="60%" height="50%">
</p>
</li>
<li><p><em><strong>네 추천합니다. 할까 말까 하시면 한번 지원은 해보죠!</strong></em></p>
</li>
</ul>
<h1 id="끝마치며">끝마치며...</h1>
<p>부스트캠프를 한창할 때는 시간이 정말 안 갔는데, 하다보니 어느새 5개월이 지나 수료도 하게 됐다. 군대 있을 때처럼 참 시간이 안 갔는데 어느 순간 확 지나가있다. 그 사이 AI 관련 실력도 늘었지만, 무엇보다도 내적으로 성숙해진 느낌이다. <del>(매우 특이한 개인적인 감상임)</del></p>
<p><del>(이상한 소리함 주의)</del>
부스트캠프를 수료하고 학교를 다니는데, 참 부스트캠프 전과 후의 마음 상태가 많이 다르다. 부스트캠프 다니는 분들은 대부분 취업을 곧장 앞두는 경우가 많은데, 이 분들과 함께 5개월의 시간을 보내니 내 마음만은 이미 졸업생에 취준생이다. 마음이 급해진 것은 아니고, 그냥 좀 특이하다. 아직 3학기나 남았지만 이미 대학교를 졸업한 그런 신기한 기분이 든다.(나뿐만 아니라 다른 재학생 분들도 그렇게 느끼는 것 같다.)</p>
<p>근데 참 다행인 것 같다. 졸업생이 아닌데 졸업을 한 느낌을 받아서 남은 3학기가 갑자기 새로 생긴 느낌이 든다. 
이제는 공부만 하는 것이 아니라 더 다양하게 학교 생활을 하고 하고 싶은 공부도 하려고 한다.
이번 학기에는 합창 동아리와 가창 수업을 신청했다. ㅋㅋ</p>
<p>6개월 후, 1년 후, ... 어떻게 내가 지내고 있을지 궁금하고 기대가 된다.</p>
<hr>
<p>저의 이력서: <a href="https://drive.google.com/file/d/1wYlUed7hrwwPNhhO5aAiHh7W91QJIWQA/view?usp=drive_link">이력서 링크</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022년 회고 및 2023년 목표]]></title>
            <link>https://velog.io/@tree_jhk/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-%EB%B0%8F-2023%EB%85%84-%EB%AA%A9%ED%91%9C</link>
            <guid>https://velog.io/@tree_jhk/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-%EB%B0%8F-2023%EB%85%84-%EB%AA%A9%ED%91%9C</guid>
            <pubDate>Sat, 31 Dec 2022 14:55:27 GMT</pubDate>
            <description><![CDATA[<h1 id="adieu-2022">Adieu 2022!</h1>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/f0821438-ea50-4f59-be04-91fb22d1d54b/image.png" alt=""></p>
<h2 id="before-i-start">Before I start</h2>
<p>2022년은 나에게는 진로를 결정 짓는 한 해였고 부스트캠프 때문에 휴학도 했던 것을 보면 나로써는 능동적으로 행동한 해였다.</p>
<h2 id="학부연구생">학부연구생</h2>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/372146d9-2764-448d-a958-23d71cb91e1b/image.png" alt=""></p>
<p>전기공학과에 AI 응용 연구를 하시는 새로운 교수님이 오셨다. 그래서 1월에 AI라는 것이 궁금하기에 공부해보고 싶은 마음에 신청하고 감사하게도 학부연구생으로 활동할 수 있었다. 이때 <a href="https://dynamic-tangelo-4e4.notion.site/SPARO-Lab-project-Drivable-region-estimation-with-Semantic-Segmentation-and-IPM-3256d7a3ce0f4b459ce507f3008129a2">학술대회에 제출할 논문</a>을 내기 위해 semantic segmentation task를 진행했다. task의 성능을 높이는 실험과 성능을 평가하는 코드를 작성하는 것이 내가 기여한 것이었다.</p>
<h4 id="딥러닝-분야에-관심이-생긴-이유">딥러닝 분야에 관심이 생긴 이유</h4>
<p>재밌던 부분은 성능이 오른만큼 semantic segmentation이 정말 눈에 띄게 잘 되었다.
그리고 성능을 높이기 위해 몇몇 기법을 적용하는 것이 재밌었다.</p>
<h4 id="학부연구생하면서-얻게-된-점">학부연구생하면서 얻게 된 점</h4>
<p>2개월 동안 학부연구생을 하면서 AI 분야에 대한 관심이 생겼고, 또한 중간중간에 발표 및 주제에 관한 의사소통을 하면서 말하기 능력이 향상되고 질문을 더 잘하게 됐다.</p>
<h2 id="clova-ai-rush-2022">CLOVA AI RUSH 2022</h2>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/a2dd9683-5e66-48db-b7a9-8019be86ad2d/image.png" alt=""></p>
<h4 id="ai-rush-지원-및-합격-그리고-깨달은-것">AI RUSH 지원 및 합격 그리고 깨달은 것</h4>
<p>AI RUSH 신청하면 떨어질 것 같아서 신청하지 말까 하다가 지인 분께서 코딩테스트도 경험할 겸 신청해보라고 말씀해주셔서 지원하게 됐다.
예상과 달리 합격할 수 있었고 2달 가량 AI RUSH에 집중하게 됐다.
정말 예상도 못한 합격이었다.
앞으로는 일단 합격할지 말지 생각하지 말고 <em><strong>JUST DO IT</strong></em> 하는 자세로 열심히 준비하고 부딪혀보고 깨져봐야겠다.</p>
<h4 id="추천시스템에-관심이-생김">추천시스템에 관심이 생김</h4>
<p>2라운드에 운 좋게 진출해서 <a href="https://github.com/tree-jhk/NAVER_AI_RUSH_2022_Music_Recommendation">음악 추천 대회</a>를 진행했다. 사용자 행동 데이터로 사용자의 마음을 딥러닝으로 예측할 수 있는 것이 즐거웠고, 더 배우고 싶어서 부스트캠프 AI Tech는 추천시스템 분야로 선택하게 됐다.(원래는 컴퓨터비전 분야를 선택하려고 했다.)</p>
<h2 id="부스트캠프-ai-tech">부스트캠프 AI Tech</h2>
<h4 id="부스트캠프에서-공부하면서-특별히-하는-것들">부스트캠프에서 공부하면서 특별히 하는 것들</h4>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/2400e5cf-4c2b-42c2-b0b7-dd5e4a0ff2df/image.png" alt="">부스트캠프라는 과정은 단 한번 밖에 못하는 과정이기 때문에 그 과정 동안 보고 배운 것들을 최대한 기록하려고 했다. 그래서 지속적으로 부스트캠프 중에 공부한 내용들과 보고 들은 강연들을 모두 노션에 작성하고 있다.</p>
<h4 id="깨달은-것">깨달은 것</h4>
<p>내가 나의 글을 통해 도움 받은 적들이 종종 있기에 잘한 선택이라고 생각한다.
추후에 저작권 관련 내용들을 제거한 노션을 공유하려고 한다.</p>
<h2 id="진로에-관해-조언-및-함께-해주신-모든-분들">진로에 관해 조언 및 함께 해주신 모든 분들</h2>
<p>이전부터 개발자가 하고 싶었지만, 재능의 영역이라고만 생각해서 쉽게 진로를 바꾸지를 못했다. 그러나 여러 고마운 분들의 조언으로 &#39;진로를 선택&#39;하고 &#39;진로를 구체화&#39;시키게 됐다.</p>
<h4 id="가족들과-사촌형들의-말들">가족들과 사촌형들의 말들</h4>
<p>가족들은 처음에는 전기공학을 버리고 컴퓨터공학쪽으로 진로를 변경한 것에 대해 걱정이 많았지만, 올해 시간이 지나면서 점점 응원을 해주고 원하는 일을 하고자 한 것은 좋은 결정이었다고 해서 감사하다.</p>
<p>사촌형들 모두 컴퓨터공학 관련 학과에서 공부를 한다. 형들의 말로는 나의 성격이나 평소 태도 그리고 선호를 봤을 때 충분히 자신감 가지고 진로를 변경해도 된다면서 주변 사람들의 이야기를 함께 꺼내주고 많은 조언을 해줬다. 참 감사하다.</p>
<h4 id="한이음-팀원들">한이음 팀원들</h4>
<p>올해 한이음 ICT 멘토링을 진행하면서 처음으로 다른 학교 학생들과 <a href="https://koreascience.kr/article/CFKO202233649408394.pdf">프로젝트</a>를 진행하는 경험을 했다. 진행하면서 서로 칭찬해주고 응원해주면서 함께 8개월이라는 시간을 같이했다. 팀원들 덕에 다양한 경험도 하고 학술대회 우수상도 수상할 수 있어서 감사하다.</p>
<h4 id="ml엔지니어로-취업한-전기공학과-선배를-만나다">ML엔지니어로 취업한 전기공학과 선배를 만나다</h4>
<p>올해 2월에 에브리타임에 &#39;전기공학과인데 AI쪽으로 진로를 전환해도 될까요?&#39;라는 내용의 글을 올렸다. 그때 ML엔지니어로 취업한 전기공학과 선배님께서 여러 조언을 해주고 충분히 커리어 전환을 할 수 있다고 말씀해주셨다. 학부연구생을 할 때도, 평소에 진로 관련해서 궁금한 것들 모두 아주 자세하게 꼼꼼하게 알려주시려고 하셨다. 또한 부스트캠프 AI Tech를 수료했다는 것도 알았고 코딩테스트를 열심히 준비하라는 말씀도 하셨다. 지금도 종종 궁금한 것이 있으면 선배님께 연락을 드린다. 항상 질문들을 잘 받아주시고 많은 것을 알려주려고 하셔서 감사하다.</p>
<p>전기공학과를 나왔음에도 충분히 ML엔지니어로 취업할 수 있는 선배님을 보고 나 또한 그렇게 될 수 있다는 확신을 갖고 진로를 바꾸기 위해 노력할 수 있게 됐다.</p>
<p>감사함이 많은 선배님이다. 나 또한 나중에 ML엔지니어로 취업해서 교내 학생들한테 도움을 줄 수 있는 그런 졸업생이 되야겠다고 다짐한다. 참 감사하다.</p>
<h4 id="부스트캠프-팀원들과-멘토님들">부스트캠프 팀원들과 멘토님들</h4>
<p>부스트캠프에서 AI 개발자를 목표로 하는 여러 사람들을 만나게 됐고 같은 관심사를 공유하는 사람들과 이야기를 많이 할 수 있어서 감사했다. 든든한 동료들과 처음으로 협업도 해보면서 소중한 시간을 보내고 있다. 다양한 배경의 사람들 속에서 많은 것을 보고 들으니 잘 성장할 수 있게 된다.</p>
<p>부스트캠프 멘토님들은 궁금하거나 진로 관련해서 질문을 하면, 정말 자세하고 꼼꼼하게 알려주시려고 했다. 덕분에 부스트캠프를 수료하는 데에 있어서 좋은 버팀목이다. 참 감사하다.</p>
<p>이제 부스트캠프 수료까지 많이 안 남았다. 1달하고 보름 정도 남았는데 많이 달려왔다. 부스트캠프에서의 인연을 소중하게 생각하고 종종 연락할 수 있도록 노력해야겠다.</p>
<p>짧게 썼지만 그 이유는 아직 수료를 안 했기 때문이다. 수료 이후에 부스트캠프 후기글을 올릴 예정이다.</p>
<h4 id="진로-고민을-나누는-친구들">진로 고민을 나누는 친구들</h4>
<p>대학교 친구 중에 좀 특별한 약속을 하게 된 친구가 있다.
&#39;진로에 있어서 잘 된 일이 생기면 그 사람이 비싼 밥 사주기&#39;를 서로 약속했고 그 친구도 나도 올해 서로 한번씩 좋은 일이 생겨서 얻어먹게 되서 즐거웠다.(저는 부스트캠프 합격, 친구는 포항공대 인턴 합격) 이런 친구를 둔 것이 참 감사하다.</p>
<p>그 외에도 진로는 다르지만 서로 진로를 응원하면서 지낸다. 취업/대학원이라는 단기적인 목표를 함께하는 친구들이 있기에 잘 정진해 나갈 수 있는 것 같다. 감사하다.</p>
<h2 id="2023년-큰-목표">2023년 큰 목표</h2>
<p>큰 새해 목표를 작성해봐야겠다.</p>
<h4 id="학부연구생-1">학부연구생</h4>
<p>추천시스템이나 NLP를 연구하는 교내 연구실에 컨택을 해서 꼭 합격해서 1년 넘게 학부연구생을 하면서 더 많은 것을 배우고 연구실에 조금이라도 기여까지 했으면 좋겠다.</p>
<h4 id="좋은-학점-따기">좋은 학점 따기</h4>
<p>대학원도 고려 중인 만큼, 학점을 높이고 싶은 욕망이 있다. 내년에 휴학 후 다시 복학할텐데 학점 잘 따는 친구들 조언 들으면서 학점을 높일 수 있으면 좋겠다.</p>
<h4 id="다이어트-하기">다이어트 하기</h4>
<p>보통 인천에서 자취를 하지만, 연말에는 본가에서 계속 있었는데 아버지 따라서 헬스장 다니면서 개운한 느낌을 받았다. 기분이 좋았고 운동해서 기분이 좋아지므로 지속적으로 운동을 해도 되겠다고 생각이 들었다.</p>
<p>그리고 1년 동안 운동량이 적은데 먹은 양은 많아서 체지방률이 증가했다. 살을 좀 빼고 헬스장 끊어서 운동을 해야겠다.</p>
<h4 id="방학-동안-기업-인턴해보기">방학 동안 기업 인턴해보기</h4>
<p>기업 중에서는 2개월 단기 인턴을 채용하는 경우가 종종 있는데, 기회가 있으면 JUST DO IT하는 마음으로 신청해서 실무를 경험해보고 싶다.</p>
<h2 id="마치며">마치며...</h2>
<p>이번 회고를 작성하면서 다음에는 회고를 어떻게 쓸지 더 많이 생각하고 쓰고 싶다는 생각이 들었다!
내년에도 좋은 사람들과 관심사를 공유하면서 즐겁게 지내고 싶다.
2023년도 참 기대되는 해이다. 나에게 어떤 재밌는 일이 올지 기대가 된다. 2023년 정말 궁금하다!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022년 여름방학 목표 결과]]></title>
            <link>https://velog.io/@tree_jhk/2022%EB%85%84-%EC%97%AC%EB%A6%84%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C-%EA%B2%B0%EA%B3%BC</link>
            <guid>https://velog.io/@tree_jhk/2022%EB%85%84-%EC%97%AC%EB%A6%84%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C-%EA%B2%B0%EA%B3%BC</guid>
            <pubDate>Fri, 30 Dec 2022 15:11:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tree_jhk/post/9121736a-2898-4a7c-be27-7f341713cf35/image.png" alt=""></p>
<p>늦었지만, 지난 목표 글인 <a href="https://velog.io/@tree_jhk/2022%EB%85%84-%EC%97%AC%EB%A6%84%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C">2022년 여름방학 목표!</a> 에서 제가 작성했던 목표들의 달성 결과를 말씀드리겠습니다!</p>
<h2 id="2022년-여름방학-목표">2022년 여름방학 목표</h2>
<h4 id="목표1-naver-clova-ai-rush-2022-2라운드-진출하기">목표1: NAVER CLOVA AI RUSH 2022 2라운드 진출하기</h4>
<p>-&gt; <strong>목표 달성 성공!</strong></p>
<ul>
<li>당시, AI RUSH 2022 2라운드에 진출할 수 있을까 긴가민가 했습니다. 대회라는 것을 처음 해보기 때문에 걱정했었습니다.</li>
<li>그래도 운 좋게 2라운드에 진출했습니다.</li>
<li>2라운드 대회로는 &quot;플레이리스트 수록곡 맞추기&quot; 대회에 참가해서 &quot;추천 시스템&quot;을 처음으로 구현해보는 시간을 가졌습니다.</li>
<li>&quot;추천 시스템&quot;이 굉장히 재밌게 느껴졌기 때문에 더 공부해보기 위해서 부스트캠프 AI Tech의 RecSys 과정을 선택하게 됐습니다. 😁</li>
<li>관련해서 당시 후기를 작성했던 글입니다: <a href="https://velog.io/@tree_jhk/CLOVA-AI-RUSH-CONFERENCE-2022">AI RUSH 2022 2라운드 후기</a></li>
</ul>
<h4 id="목표2-한이음---뉴스-기사의-감정분석을-통한-비트코인-주식-가격-예측하기">목표2: 한이음 - 뉴스 기사의 감정분석을 통한 비트코인 주식 가격 예측하기</h4>
<ul>
<li>네 이 목표도 달성했었고 데이터셋을 제작하는 경험을 할 수 있었습니다.</li>
<li>다만, 당시 저를 포함해서 팀원들 모두 감정분석 결과를 어떻게 임베딩으로 넣을지 몰랐기 때문에 사용하지 못했습니다 😭 (지금의 저는 할 수 있습니다 😁)</li>
<li>제작한 데이터셋에 대한 노션 글입니다: <a href="https://dynamic-tangelo-4e4.notion.site/Dataset-1-Bitcoin_News_Title_Upbit_Price_Sentiment-csv-raw-27568dd480ef49e2867df798f6089fee">암호 화폐 감정분석 데이터셋</a></li>
</ul>
<h4 id="목표3-naver-부스트캠프-ai-tech-합격을-위한-코딩테스트-준비">목표3: NAVER 부스트캠프 AI Tech 합격을 위한 코딩테스트 준비</h4>
<ul>
<li>부스트캠프 AI Tech 준비가 AI RUSH 대회와 겹치면서, 당시 작성한 글만큼 준비하지는 못했지만, 다행히도 부스트캠프 AI Tech에 합격할 수 있었습니다.</li>
<li>그때 오픈채팅방에서 팀원들을 구해서 같이 스터디 형식으로 공부했었는데 그때 강제적으로 코딩테스트 준비했던 경험이 큰 도움이 됐다고 생각합니다!</li>
<li>지금 생각해보면, 당시 작성한 글만큼 코딩테스트 하는 것은 양적으로 불가능한 것 같습니다 ㅋㅋ</li>
</ul>
<h4 id="목표4-토익-950점-이상-받기">목표4: 토익 950점 이상 받기</h4>
<ul>
<li>토익 공부 하나도 안했습니다 ㅠ ㅋㅋㅋ</li>
<li>그래도 부스트캠프 하면서 강제적으로 영어 논문 읽으면서 부족했던 독해 실력이 조금이라도 길러지지 않았을까 생각합니다 ㅎㅎ</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[3차원 텐서 요소 추출 후 2차원 텐서 변형 시키기(torch.gather 이용)]]></title>
            <link>https://velog.io/@tree_jhk/3%EC%B0%A8%EC%9B%90-%ED%85%90%EC%84%9C-%EC%9A%94%EC%86%8C-%EC%B6%94%EC%B6%9C-%ED%9B%84-2%EC%B0%A8%EC%9B%90-%ED%85%90%EC%84%9C-%EB%B3%80%ED%98%95-%EC%8B%9C%ED%82%A4%EA%B8%B0torch.gather-%EC%9D%B4%EC%9A%A9</link>
            <guid>https://velog.io/@tree_jhk/3%EC%B0%A8%EC%9B%90-%ED%85%90%EC%84%9C-%EC%9A%94%EC%86%8C-%EC%B6%94%EC%B6%9C-%ED%9B%84-2%EC%B0%A8%EC%9B%90-%ED%85%90%EC%84%9C-%EB%B3%80%ED%98%95-%EC%8B%9C%ED%82%A4%EA%B8%B0torch.gather-%EC%9D%B4%EC%9A%A9</guid>
            <pubDate>Tue, 04 Oct 2022 00:55:04 GMT</pubDate>
            <description><![CDATA[<p>3차원 텐서에서 특정한 규칙으로 추출하고자 하는 요소들을 2차원 텐서로 제작하고 싶은 그런 경우가 종종 있습니다(?) (특히 빡센 dataloader 제작할 때나 모델 제작할 때?)
그럴 때 빠르게 추출할 수 있는 <strong>torch.gather을 이용한 방식</strong>을 사용할 수 있습니다!!</p>
<h1 id="torchgather-이해하기">torch.gather 이해하기</h1>
<p><a href="https://pytorch.org/docs/stable/generated/torch.gather.html#torch.gather">toch.gather 에 대한 PyTorch documentation</a> documentation을 보면, 사실 잘 이해가 안 갑니다.
저는 이렇게 정성적으로 이해해보는게 쉬운 것 같습니다:</p>
<blockquote>
<p><strong><em>torch.gather(input, dim, index, *, sparse_grad=False, out=None) → Tensor</em></strong>
torch.gather(추출하려는 텐서, 추출하려는 텐서에서 어떤 차원을 참고할 것인지?, 해당 차원에서 몇 번째 index 요소들을 참고할 것인지)</p>
</blockquote>
<h4 id="주의할-것">주의할 것:</h4>
<ol>
<li>torch.gather은 텐서의 추출하고자하는 요소들 하나하나를 직접 접근해야한다는 것을 인지해야합니다.</li>
<li>[추출하려는 텐서에서 어떤 차원을 참고할 것인지?]</li>
</ol>
<p>-&gt; 2번째 매개변수인 _<strong>dim</strong>_은 추출하고자하는 원소들의 차원을 입력해주시면 됩니다. (= 3차원 텐서이면 C H W 중에 W 부분)
-&gt; 3차원 텐서의 요소를 추출하려면 dim=2
-&gt; 2차원 텐서의 요소를 추출하려면 dim=1
3. [해당 차원에서 몇 번째 index 요소들을 참고할 것인지] 
-&gt; 3번째 매개변수인 _<strong>index</strong>_는 torch.tensor() 형식으로 추출하려는 요소들을 묶어줘야 합니다.
-&gt; <strong>index 부분이 제일 핵심이고 어렵습니다!!</strong></p>
<p>이해를 돕기 위한 예시: </p>
<h1 id="3차원-텐서의-대각선-원소들을-담은-2차원-텐서-만들기">3차원 텐서의 대각선 원소들을 담은 2차원 텐서 만들기</h1>
<h2 id="tensor의-변화-과정을-살펴봅니다">tensor의 변화 과정을 살펴봅니다!</h2>
<blockquote>
<p>우선 <strong>input</strong>, <strong>torch.gather을 통한 결과</strong>, 그리고 <strong>output 결과</strong>부터 확인해봅니다!</p>
</blockquote>
<h4 id="input-예시">input 예시:</h4>
<pre><code class="language-python">input = torch.tensor(
        [[[5,4,3],
          [7,6,2]],
         [[3,2,1],
          [1,2,8]]])
print(input.size())
&gt;&gt;&gt;torch.Size([2, 2, 3])</code></pre>
<h4 id="torchgather-후-결과">torch.gather 후 결과:</h4>
<pre><code class="language-python">gather_result = torch.tensor(
    [[[5],[6]],
     [[3],[2]]]
)
print(gather_result.size())
&gt;&gt;&gt;torch.Size([2, 2, 1])</code></pre>
<h4 id="output-결과">output 결과:</h4>
<pre><code class="language-python">output = torch.tensor(
        [[5,6],
         [3,2]])
print(output.size())
&gt;&gt;&gt;torch.Size([2, 2])</code></pre>
<h3 id="위-예시를-통해-파악할-것">위 예시를 통해 파악할 것</h3>
<ol>
<li>위에서 이야기한 것처럼, <strong>torch.gather는 텐서의 각 원소들을 하나하나씩 가져온다고 했습니다.</strong> 실제로 gather_result 를 보시면 3차원 텐서의 결과로 <strong>각 원소들이 하나하나 별개의 크기가 1인 1차원 텐서로 구분된 것</strong>을 확인할 수 있습니다. </li>
</ol>
<p>-&gt; 따라서 <strong>torch.size()를 찍어보면, dim=2일 때의 size가 1인 것을 확인할 수 있죠!</strong>
2. torch.gather 결과는 원소 하나하나가 각각 별개의 크기가 1인 1차원 텐서로 구분되어있기 때문에 view나 reshape나 squeeze를 활용해서 차원을 맞춰줘야 합니다</p>
<h2 id="3차원-텐서---2차원-텐서로-변화해가는-과정">3차원 텐서 -&gt; 2차원 텐서로 변화해가는 과정</h2>
<blockquote>
<p>3차원 tensor의 대각 요소들을 추출하기 위한 과정들을 step by step으로 알아보겠습니다~</p>
</blockquote>
<ol>
<li>3차원 텐서의 C, H, W 추출하기<pre><code class="language-python">A = torch.tensor(
     [[[5,4,3],
       [7,6,2]],
      [[3,2,1],
       [1,2,8]]])
C,H,W = A.size()
print(C,H,W)
&gt;&gt;&gt;2 2 3</code></pre>
</li>
<li>3차원 텐서의 대각 요소들의 길이 구하기 (가로, 세로 길이가 다른 경우를 위해)<pre><code class="language-python">A = torch.tensor(
     [[[5,4,3],
       [7,6,2]],
      [[3,2,1],
       [1,2,8]]])
C,H,W = A.size()
# diag_size: 대각 요소들의 길이
diag_size = min(H,W)
print(diag_size)
&gt;&gt;&gt;2</code></pre>
</li>
<li>대각 요소들의 인덱스를 저장하는 1차원 텐서 만들기(gather의 인덱스로 사용될 부분)<pre><code class="language-python">A = torch.tensor(
     [[[5,4,3],
       [7,6,2]],
      [[3,2,1],
       [1,2,8]]])
C,H,W = A.size()
# diag_size: 대각 요소들의 길이
diag_size = min(H,W)
# rng는 대각선 요소들의 index를 저장한 1차원 tensor
rng = torch.arange(diag_size)
print(rng)
&gt;&gt;&gt;tensor([0, 1])</code></pre>
</li>
<li>대각 요소들의 인덱스들을 별개의 크기가 1인 1차원 텐서 형태로 나누기<pre><code class="language-python">gather_index = rng.view(len(rng),-1)
print(gather_index)
&gt;&gt;&gt;tensor([[0],
     [1]])</code></pre>
</li>
<li>추출하고자 하는 3차원 텐서의 Channel 값(위에서 구한 C)만큼 gather_index 반복하기 (torch.expand) 사용 
<a href="https://pytorch.org/docs/stable/generated/torch.Tensor.expand.html?highlight=expand">torch.Tensor.expand</a>: 텐서를 어떤 형태로 확장할 것인가에 대한 함수</li>
</ol>
<p>-&gt; <strong>주의할 것: 아래 코드의 torch.expand의 마지막 매개변수 부분은, 각 원소(대각 요소들의 인덱스)를 별개로 저장하기 때문에 이를 고려한 부분입니다. 코드에서 다시 설명했습니다.</strong></p>
<pre><code class="language-python"># 아래와 같이, dim=2에 해당하는 부분을 1로 지정했습니다.
# diag_size는 H, W 중 하나입니다. 대각 요소들을 추출하기 위함입니다.
gather_index = gather_index.expand(C,diag_size,1)
print(gather_index)
&gt;&gt;&gt;tensor([[[0],
         [1]],

        [[0],
         [1]]])</code></pre>
<ol start="6">
<li><p>1단계~5단계를 통해, <strong><em>torch.gather(input, dim, index, *, sparse_grad=False, out=None) → Tensor</em></strong> 해당 부분에서 index에 해당하는 부분을 드디어 완성했습니다. 이제 output을 생성하겠습니다!</p>
<pre><code class="language-python"># dim=2로 둬서, 3차원 텐서인 A의 각 요소들에 접근할 수 있도록 합니다.
# index는 3차원 텐서인 A에서 접근하고자하는 요소들의 위치를 다음 gather_index로 지정합니다.
output = torch.gather(input=A,dim=2,index=gather_index)
print(output)
&gt;&gt;&gt;tensor([[[5],
      [6]],

     [[3],
      [2]]])</code></pre>
<p>완성했습니다!</p>
<h1 id="의의">의의</h1>
<p>이 글은 3차원 텐서에서 대각 요소들을 추출하는 경우를 예시로 들었습니다.(부스트캠프 내용을 참고해서 만들었어요) 이 과정을 알고리즘 문제 해결하듯이 직접 알고리즘이랑 텐서 변화 과정을 그려보면서 작성하다보면 잘 이해될 것 같습니다.
또한 나중에 3차원 텐서에서 요소를 추출할 때 해당 글에서와 같은 사고과정으로 요소를 추출하는 방법에 대해 생각하고 알고리즘을 설계하면 원하는 값들을 자유자재로 추출할 수 있게 될 것 같습니다!</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CLOVA AI RUSH CONFERENCE 2022 후기 feat. Music AI 팀과의 QnA]]></title>
            <link>https://velog.io/@tree_jhk/CLOVA-AI-RUSH-CONFERENCE-2022</link>
            <guid>https://velog.io/@tree_jhk/CLOVA-AI-RUSH-CONFERENCE-2022</guid>
            <pubDate>Wed, 07 Sep 2022 11:12:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tree_jhk/post/e618c3da-5bbc-4c8c-b60c-a24e34aa3efa/image.png" alt=""></p>
<h1 id="clova-ai-rush-conference-2022-소개">CLOVA AI RUSH CONFERENCE 2022 소개</h1>
<p>이번에 CLOVA AI RUSH 2022을 수료했던 사람들을 포함해서 외부에 퍼블릭하게 공개된 컨퍼런스가 주최됐다.
 위 사진에서처럼 _<strong>네이버의 최신 AI 기술들을 알 수 있는 아주 좋은 기회</strong>_였다. 내년에도 rush에 참여를 못해도 본 컨퍼런스는 꼭 참여하고 싶다.</p>
<h1 id="music-ai-팀-부스-질의응답">Music AI 팀 부스 질의응답</h1>
<p><strong>(답변을 구두로 받았기 때문에 작성한 간단한 메모들에 기반해서 간단히 작성합니다 ㅋㅋ)
(주관적으로 볼 때, deep한 내용은 올리지 않았습니다 ㅋㅋ)</strong></p>
<h3 id="q1-music-ai-팀에서는-딥러닝머신러닝을-어떻게-활용-중인가요">Q1: Music AI 팀에서는 딥러닝/머신러닝을 어떻게 활용 중인가요?</h3>
<p>A: Music AI 팀은 음악 추천시스템을 구현하기 위해 CF, MF, AE 등을 활용하고 log 데이터를 기반으로 추천하려고 합니다.
또한 메타데이터에서 적절한 latent vector를 도출합니다.</p>
<h3 id="q2-논문-구현-역량이-중요할텐데-어느-정도로-알아야할까요">Q2: 논문 구현 역량이 중요할텐데, 어느 정도로 알아야할까요?</h3>
<p>A: <em><strong>구현한 논문에서 모델이 어떻게 동작하는지 정확히 이해하고 설명할 수 있는지 알아야 합니다. 또한 주어진 문제(task)를 해결하기 위해 저자는 어떤 직관이나 가정을 했고 왜 해당 모델을 사용했고 가정했던 내용들이 정말 맞아떨어지는지</strong></em> 등 (잘 기억이 안남) 을 알아야 합니다. 확실한 검증을 할 필요가 있습니다.</p>
<h3 id="q3-이번-플레이리스트-음악-추천-과제에서-word2vec을-도입해봤는데-빈도-기반이-아닌-주변-단어-기반의-알고리즘이라-그런지-최적화한-오토인코더-모델보다-성능이-안-나왔습니다-왜-그랬을까요">Q3: 이번 플레이리스트 음악 추천 과제에서 word2vec을 도입해봤는데 빈도 기반이 아닌 주변 단어 기반의 알고리즘이라 그런지, 최적화한 오토인코더 모델보다 성능이 안 나왔습니다. 왜 그랬을까요?</h3>
<p>A: Bag of Words 를 썼으면 성능 향상을 기대해볼 법했을 것이라고 생각합니다.</p>
<p>이에 대한 나의 생각: 아마 이번 과제에서 input으로 여러 문자열 데이터들을 집어넣을 때, 뭔가 단어 간에 순서가 사실상 없기 때문이다.(가사1+장르1+가수1+가사2+장르2+가수2+가사3+장르3+가수3+ ... + 가사n+장르n+가수n 이런 식으로 하나의 문자열을 구성하는데 이거는 사실상 노래i와 노래j의 메타데이터간에 연관 관계가 없을 수도 있고, 확실한 것은 이렇게 문자열을 구성하면 순서가 무의미해진다.)
따라서, 만약 이 과제에 <em><strong>Bag of Words를 썼다면, 단어들의 순서에 상관없이 많이 등장하는 단어에 맞춰서 플레이리스트의 분위기를 구해낼 수 있었을 것 같다. 하셨던 말씀이 잘 기억은 안나지만 아마 이런 이유이지 않을까 싶다.</strong></em>
-&gt; Bag of Words를 활용하는 추천 시스템 논문들을 찾아보고 이해해보고 구현해봐야겠다!!</p>
<h3 id="q4-music-ai-팀에-합류하기-위해서는-어떤-역량을-갖춰야할까요">Q4: Music AI 팀에 합류하기 위해서는 어떤 역량을 갖춰야할까요?</h3>
<p>A: <em><strong>새로운 지식들을 최신 논문을 통해 습득하고 데모 정도로 구현하고 리뷰할 수 있는 능력이 필요합니다.
 추천 시스템 모듈을 서비스할 수 있는 역량이 있으면 좋습니다. 기획자와의 원활한 커뮤니케이션 역량이 있어야겠습니다.</strong></em></p>
<h1 id="느낀점">느낀점</h1>
<p><em><strong>네이버 AI 기술은 기업에도 제공된다!</strong></em>
나는 네이버 AI 서비스들 팬이지만(Papago, Whale, 네이버 사전, 네이버 지도, 네이버 앱, 클로바노트 를 자주 사용한다.) 내가 알고 있는 것보다 훨씬 다양하게 네이버에서 AI 서비스들을 출시했고 <em><strong>비단 일반인뿐만 아니라 기업을 대상으로 좀 더 편한 서비스를 제공할 수 있도록 상담 내용 분석 등을 진행한 것을 알 수 있었다.</strong></em>
 네이버는 HyperClova를 창의적으로 응용해서 다양한 서비스를 제공한다는 것을 알 수 있었다.
신기하게 이번 플레이리스트 음악 추천 과제에서 수상한 1~3등 분들은 CV와 NLP 모델을 활용해서 본 대회에서 수상했다.
 <em><strong>모델에 대한 이해가 확실히 되어있어야 특정 모델을 사용하면 피처가 잘 추출될 것이다라는 직관이나 논리적인 근거가 생길 것 같다고 느꼈다.</strong></em>
다른 분들도 거의 근접한 스코어를 가졌어가지고 그 분들의 접근도 매우 궁금하다...</p>
<p>올초부터 papago와 클로바노트 쓰면서 네이버의 AI 기술들에 관심이 가기 시작했는데 이번 [CLOVA AI RUSH CONFERENCE 2022]을 통해 어떤 기술들이 있고 어떻게 구현했는지 들을 수 있어서 즐거웠다.</p>
<p>또한 공유하면 좋을 내용들이 있는 것 같아서 글을 작성하게 됐다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트캠프 AI tech 4기 합격 후기 - 1차 코딩테스트]]></title>
            <link>https://velog.io/@tree_jhk/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%94%84-AI-tech-4%EA%B8%B0-1%EC%B0%A8-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%94%84-AI-tech-4%EA%B8%B0-1%EC%B0%A8-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Fri, 05 Aug 2022 06:44:51 GMT</pubDate>
            <description><![CDATA[<p>코딩테스트 문제는 <strong>총 5문제</strong>가 출제됐고 그 <strong>중 3.5문제를 풀었다.</strong>
AI 수학 문제는 <strong>총 20문제</strong>가 출제됐고 그 <strong>중 20문제를 풀었다.</strong>
간단한 사전 조사하는 문제는 <strong>총 5문제</strong>가 출제됐다.(선발에 영향이 전혀 없는 설문이다.)
<strong>총 2시간</strong>이 주어졌고, <strong>Python으로 풀었다.</strong></p>
<p>주요한 특징은</p>
<ol>
<li><strong>종이, 펜 없이 쌩으로 프로그래머스 IDE 환경</strong>으로 코딩테스트 문제를 풀어야 했고, <strong>당연히 수학과 AI문제들을 암산</strong>해야 했다.</li>
<li>화면 공유를 해야했고 휴대폰 카메라로 측면을 비춰야했다.</li>
<li>시험은 19:30 ~ 21:30으로 2시간이 주어졌다.</li>
<li>미리 온라인상에 19:00까지는 접속해서 준비가 되어 있어야 했다.</li>
<li>투명한 컵이나 병에 담긴 물 이외에 다른 음료나 과자는 섭취 불가였다.</li>
<li>5솔브는 거의 없었다.(오픈카톡방 투표 참고)
<img src="https://velog.velcdn.com/images/tree_jhk/post/5fa7dfe4-98ab-499d-8cba-84a46075426f/image.png" alt="">
4솔이 아닌 3.5솔이라 그냥 3솔로 체크했다.
마지막 항목은 0솔이나 5솔 중에 하나인데, 0솔이 거의 없는 걸로 보이는 이유는 0솔이신분들은 카톡방을 투표 전에 이미 나가신 경우가 많았다.</li>
<li>플레5이신 분이 3.5솔 골드2이신 분이 2.5솔했던 어려운 난이도였다.</li>
<li>이론 문항들도 모든 문제들이 자가 진단 문제들보다는 조금 더 어려웠다. 근데 암산+문항 수가 훨씬 많고 코테도 어려웠어서 공부를 많이 안했으면 잘 못 풀었을 것이다. 본인은 모르는 문제는 그냥 대충 아는대로 찍고 아는건 빨리 계산해서 풀었다. 다양하게 지식을 접하는 게 중요해 보인다. AI와 수학 관련 외에는 넘파이 판다스 파이토치 파이썬 파이썬고급문법 문항은 한 문항도 출제되지 않았다.</li>
</ol>
<p><strong>1번 문제:</strong>
난이도: 백준 브론즈1~실버5 -&gt; Solved
처음으로 진짜 꼭 붙어야하는 감정이 들어서인지 1번 문제가 분명히 쉬운 문제인 것은 느껴졌는데 잘 안 풀렸다. 시행착오를 좀 겪고 침착하게 다시 풀어서 20분 정도 걸렸다.
뭔가 기억은 안나지만 정렬이나 딕셔너리를 활용해야 했던 것 같다.</p>
<p><strong>2번 문제:</strong>
난이도: 백준 실버4~실버2 -&gt; Solved
이거는 아마 permutations를 알면 쉽게 풀 수 있었던 문제였던 거 같긴한데 그래도 어려운 문제였다. 구현 문제.
30분 정도 걸렸다.</p>
<p><strong>3번 문제:</strong>
난이도: 백준 실버1~골드5 -&gt; Solved
문제가 괴상하게 막 회전하고 그런 문제가 있어서 그냥 넘겼다. 이거는 뭔가 풀다가 다른 문제들을 놓칠 것 같다는 느낌이 들었다.</p>
<p><strong>4번 문제:</strong>
난이도: 백준 실버2~실버1 -&gt; Solved
구현을 열심히 열심히 해서 겨우겨우 풀었다.
이 문제는 제대로 풀었던 것 같다. n제한이 작아서 완전탐색으로 해결했다.
이 또한 permutations를 이용한 것으로 기억한다.
이 문제도 오래 걸렸다. 30분 넘게.</p>
<p><strong>5번 문제:</strong>
난이도: 백준 골드5 이상 -&gt; Solved
이 문제를 0.5솔 했다. 좀 아쉽다. 거의 다 풀었는데 시간이 부족했다. 어느 부분이 잘못된지를 파악했을 때 시간은 3분 밖에 안 남았다. 분명히 꼼꼼히 생각했으면 if문 추가해서 해결했을 수도 있었을 것 같은데 아쉽다.
AI 지식 시험이 있어서 시간이 부족했다.</p>
<p>듣기로는 dp로 해결하면 쉬웠다고 한다.</p>
<p>전반적으로 다음 기수에서 준비를 한다면, AI 시험을 빠르게 풀 수 있도록 대비를 좀 많이 해놓고, 코딩테스트의 경우는 본 글에서 작성한 난이도를 고려해서 구현 문제(완전탐색) 문제 위주로 풀면 좋을 듯하다.</p>
<p>1차 시험 때는 dp말고는 딱히 특별한 알고리즘을 알아야 풀 수 있던 문제는 없던 것 같다. 다만 그냥 대표적인 알고리즘 문제들은 혹시 모르니 공부해보는 것이 좋을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CLOVA AI RUSH 1라운드 후기 과제명: Landmark Image Classification feat. 코딩테스트 내용 포함]]></title>
            <link>https://velog.io/@tree_jhk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%B4%88%EB%B3%B4%EC%9D%98-AI-RUSH-%ED%9B%84%EA%B8%B0-1%ED%8E%B8</link>
            <guid>https://velog.io/@tree_jhk/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%B4%88%EB%B3%B4%EC%9D%98-AI-RUSH-%ED%9B%84%EA%B8%B0-1%ED%8E%B8</guid>
            <pubDate>Sun, 10 Jul 2022 06:20:17 GMT</pubDate>
            <description><![CDATA[<p>1라운드 대회는 7월 말에 끝났지만 이제야 후기를 작성하게 됐다.</p>
<h1 id="러쉬에-참여하게-된-계기">러쉬에 참여하게 된 계기</h1>
<p>굳이 쓸 필요 있나 싶긴한데, 좀 극적이어서 적어본다. 원래는 스스로 매우 부족한 걸 알았기 코딩테스트가 있는 AI RUSH 2022에 선발도 안될 것 같았고 선발되더라도 매우 못할 것으로 전망했다. 왜냐면 딥러닝 관련 실력도 지식도 부족하고 파이썬으로 코딩테스트만 준비해본 경험이 대부분이었기 때문이다. 그런데 현직 개발자 지인 분께서 한번 지원해보라고 권유를 해봐서 이왕할거 열심히 준비했는데 학부연구생 때 했던 프로젝트가 어필이 잘 되어서인지 얼떨결에 선발됐다. 덕분에 <strong>매우매우매우 좋은 경험을 할 수 있었다.</strong></p>
<h1 id="코딩테스트-결과">코딩테스트 결과</h1>
<p>2시간 동안 풀어야 했고 4문제가 출제됐고 4문제 모두 빡구현 문제였다. 그 중에서 2문제를 풀었다.
떨어질 각오였기 때문에 2문제라도 제대로 풀자는 마음이 있었다. 테스트케이스가 히든테스트케이스였기 때문에 매우 꼼꼼하게 로직을 검증하고 테케도 추가해서 검증을 나름 열심히 하고 다른 문제를 해결해보려고 했고 결과적으로 2문제를 제대로 풀고 합격할 수 있었다.</p>
<p>1솔 합격은 못 봤고 2솔부터 합격하신 분들이 계신 걸로 기억한다.</p>
<p>다음에 러쉬에 지원한다면 꼭 3문제를 풀고 합격하고 싶다.</p>
<h1 id="본인의-베이스">본인의 베이스</h1>
<p>AI RUSH에 참여하게 된 나는 사실 딥러닝 이론은 자세히는 모르는 편이었고 파이토치 코딩만 조금 할 줄 아는 수준이다.(파이썬, C++로 백준 골드4, 프로그래머스 100문제 풀이)</p>
<p>이론도 부족하고 학기 동안은 딥러닝을 하나도 공부를 안했어가지고 나의 베이스로는 AI RUSH 대회가 어렵게 느껴졌다. 그래도 2라운드에 꼭 진출하고 싶은 생각은 있어가지고 딥러닝 이론들 및 파이토치 코드들에 대해서 전보다 자세하게 배우기 시작했다. 공식 문서의 튜토리얼들을 한번 쭉 돌려봤다.</p>
<h1 id="과제-선택-과정">과제 선택 과정</h1>
<p>과제가 총 4개가 주어졌고 그 중에서 1개를 최종적으로 선택해야 했다.
과제 중 하나는 tensorflow를 사용하기 때문에 pass했다.
나머지 3개 과제는 nlp과제 1개 cv과제 2개가 있었다.
nlp는 공부해보고 싶었지만 지금 당장 대회에서 결과를 낼 수는 없어서 pass했다.
그래서 cv과제 2개 중에 하나를 해야했는데, 이미지를 직접 안 봐도 퍼포먼스를 낼 수 있는 과제인 Landmark classificiation (이미지 분류 task)을 진행했다.</p>
<h1 id="과제-수행-과정과-결과">과제 수행 과정과 결과</h1>
<p>내가 선택한 과제는 flops 제한이 있어가지고 제한된 연산량 안에서 결과를 극대화해야 했다. 그래서 많은 분들이 연산량이 제한된 값에 못 미치는 약한 모델들을 앙상블해서 문제를 해결했다고 했다. (이때 처음으로 앙상블이라는 기법을 알게 됐다...)</p>
<p>나는 앙상블을 어떻게 할지를 몰라서 단일 모델로 승부를 보기로 했다. 그래서 flops 제한 사항 안에서 pre-trained 모델 중에 제일 성능이 높은 모델을 가져다가 하이퍼파라미터 튜닝 실험을 많이 진행했다. 다행히도 학부연구생 때 했던 거랑 유사한 상황이어서 그런지 실험을 잘 진행할 수 있었다.</p>
<p><a href="https://dynamic-tangelo-4e4.notion.site/NAVER-AI-RUSH-2022-ROUND-1-Landmark-image-classification-d6d89a3abc1d4074878a6761da56a81f">당시의 rush 진행 과정</a></p>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/328068a1-3916-437b-9e1e-18903028b064/image.png" alt="">
결과적으로, 27명 중에 17등을 해서, 18등에 들어서 2차 라운드에 진출할 수 있게 됐다.
-&gt; 2차 라운드 후기도 작성할 예정</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022 Dev-Matching: 웹 백엔드 개발자(상반기) 코딩테스트 후기]]></title>
            <link>https://velog.io/@tree_jhk/2022-Dev-Matching-%EC%9B%B9-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%83%81%EB%B0%98%EA%B8%B0-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/2022-Dev-Matching-%EC%9B%B9-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%83%81%EB%B0%98%EA%B8%B0-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sun, 03 Jul 2022 03:36:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tree_jhk/post/c7486795-fc65-4be1-9c0d-4395dda9da08/image.png" alt=""></p>
<p>코딩테스트 문제는 <strong>알고리즘 3문제 SQL 1문제:</strong> <strong>총 4문제</strong>가 출제됐고 그 <strong>중 알고리즘 3문제를 풀었다.</strong>
<strong>총 2시간</strong>이 주어졌고, <strong>Python으로 풀었다.</strong></p>
<p><strong>1번 문제:</strong>
난이도: 백준 브론즈1~실버5 -&gt; Solved
구현 문제이긴 한데, 따지고 보면 그리디 유형 같다.
아주 가볍게 생각하고 3분만에 풀고 예시 테스트 케이스를 돌렸을 때 정답이 나와서 실행했더니 10개 중에 7개가 틀렸었다.
그래서 반례를 생각하고 하여튼 좀 헤매다가 겨우 풀었다.
푸는데 20분 정도 소요됐다.</p>
<p><strong>2번 문제:</strong>
난이도: 백준 실버2~실버1 -&gt; Solved
로봇 청소기가 등장해서, DFS BFS 유형인가 싶었다. 그런데 이거는 뭐 전혀 처음 보는 느낌이었다.
규칙을 찾으려고 노력했다. 그래서 결국 찾아냈고 답을 구했다.
푸는데 30분 정도 걸렸다.</p>
<p><strong>3번 문제:</strong>
난이도: 백준 실버1~골드5 -&gt; Solved
전형적인 삼성 코딩테스트 유형의 문제였다. 최근에 삼성 유형을 풀어봤어가지고 한번 도전해봤다. 당장 별 생각 없이 DFS로 풀어야겠다는 생각을 갖고 DFS로 쭉 밀고 갔다. 그런데... DFS가 프로그래머스 상에서 좀 쓰기에 고려할 부분들이 좀 있다.</p>
<ol>
<li>solution()함수 내부에서 선언한 변수들에 대해서 dfs() 함수에도 쓰이려면 함수 각각에 대해서 global을 처리해줘야 했다. 이거 때문에 굉장히 곤란했다.</li>
<li>DFS를 할려면, 
import sys
sys.setrecursionlimit(10**9)
이 구문을 반드시 추가해줘야 한다. 그냥 아무 생각없이 추가해야겠다. 런타임에러가 엄청 떠서 굉장히 당황했다. 다행히도 추가 후에 해결이 됐다. 푸는데 총 1시간이 걸렸다.</li>
</ol>
<p><strong>4번 문제</strong>
SQL은 저번 인턴매칭 때 열심히 대비했는데 엄청 어려웠다. 이번에는 준비 안하고 그냥 코테만 기다렸었다. 이번 SQL문제도 내가 설사 벼락치기 했어도 어차피 모르는 유형이었다. 랭크와 서브쿼리를 활용해야 한다고 들었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RNN 실험 - 활성화 함수를 바꾸면 성능이 어떻게 변할까? (+Dropout 적용 +LSTM 적용)]]></title>
            <link>https://velog.io/@tree_jhk/RNN-%EC%8B%A4%ED%97%98-%ED%99%9C%EC%84%B1%ED%99%94-%ED%95%A8%EC%88%98%EB%A5%BC-%EB%B0%94%EA%BE%B8%EB%A9%B4-%EC%84%B1%EB%8A%A5%EC%9D%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%B3%80%ED%95%A0%EA%B9%8C-LSTM-%EC%A0%81%EC%9A%A9</link>
            <guid>https://velog.io/@tree_jhk/RNN-%EC%8B%A4%ED%97%98-%ED%99%9C%EC%84%B1%ED%99%94-%ED%95%A8%EC%88%98%EB%A5%BC-%EB%B0%94%EA%BE%B8%EB%A9%B4-%EC%84%B1%EB%8A%A5%EC%9D%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%B3%80%ED%95%A0%EA%B9%8C-LSTM-%EC%A0%81%EC%9A%A9</guid>
            <pubDate>Tue, 28 Jun 2022 17:39:40 GMT</pubDate>
            <description><![CDATA[<p><strong>기본적인 형태의 RNN(Vanila RNN)의 문제점</strong>은 <strong>long term일수록 과거의 정보가 손실</strong>이 되기가 쉬워서 <strong>단기 기억</strong>밖에 못하는 문제점이 있다.
<img src="https://velog.velcdn.com/images/tree_jhk/post/a263531b-4422-48b4-acf1-4fa253210c21/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/a860dec4-276c-46bf-b488-b512223800ee/image.png" alt=""></p>
<p>단적으로, 위의 식은 <strong>정보 h_4를 얻기 위해</strong>, <strong>과거 정보인 h_0에서부터 지속적으로 가중치를 곱해야 한다.</strong></p>
<h3 id="위-식으로-다음의-2가지-문제점들을-알-수-있다">위 식으로 다음의 <strong>2가지 문제점</strong>들을 알 수 있다.</h3>
<ol>
<li><p>가중치 W와 정보 h_0가 모두 양수일 때, <strong>활성화 함수로 ReLU 함수를 사용</strong>하면, h_0를 계속 bypass해서 h_0에 계속 W가 곱해진다. 이렇게 되면 <strong>과거 정보인 h_0가 출력에 매우 크게 반영</strong>된다. -&gt; <strong>exploding gradient 문제 발생</strong></p>
</li>
<li><p>만약 가중치 W와 곱한 것이 음수가 나오고, <strong>활성화 함수로 sigmoid 함수를 사용</strong>하면, <strong>과거 정보가 계속 소실</strong>되면서, 결국 <strong>vanishing gradient 문제가 발생</strong>한다.</p>
</li>
</ol>
<p>활성화 함수들:
<img src="https://velog.velcdn.com/images/tree_jhk/post/234ca03b-41a9-4aef-9212-497a2648c116/image.png" alt=""></p>
<h3 id="위의-2가지-문제점들로-생긴-궁금증">위의 2가지 문제점들로 생긴 궁금증:</h3>
<ol>
<li>활성화 함수만 바꾼다고, 1번 문제점인 exploding gradient 문제를 해결할 수 있을까? 그나마 leaky ReLU나 Hyperbloic Tangent를 사용하면 음수값에 대해서 정보를 어느 정도는 다음 시점에 넘겨주기 때문에 학습이 더 잘 될 것 같다.</li>
<li>2번 문제인 vanishing gradient 문제도 뭔가 leaky ReLU나 Hyperbloic Tangent를 사용하면 음수값에 대해서 정보를 어느 정도는 다음 시점에 넘겨주기 때문에 학습이 더 잘 될 것 같다.</li>
</ol>
<h3 id="실험-세팅">실험 세팅:</h3>
<p>데이터셋: torchtext.legacy.datasets에서 제공하는 IMDB의 영화 리뷰 데이터셋
공통적인 RNNCell_Encoder:</p>
<pre><code class="language-python">class RNNCell_Encoder(nn.Module):
    def __init__(self,input_dim,hidden_size):
        super(RNNCell_Encoder,self).__init__()
        self.rnn = nn.RNNCell(input_dim,hidden_size)

    # RNN의 foward를 초기화
    def forward(self,inputs):
        bz = inputs.shape[1]
        ht = torch.zeros(bz,hidden_size).to(device)
        for word in inputs:
            ht = self.rnn(word,ht)</code></pre>
<p>대조군 ReLU 사용:</p>
<pre><code class="language-python">class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.em = nn.Embedding(len(TEXT.vocab.stoi),embeding_dim)
        self.rnn = RNNCell_Encoder(embeding_dim,hidden_size)
        self.fc1 = nn.Linear(hidden_size,256)
        self.fc2 = nn.Linear(256,3)

    def forward(self,x):
        x = self.em(x)
        x = self.rnn(x)
        x = F.relu(self.fc1(x))
        x = F.sigmoid(self.fc1)
        x = F.leaky_relu
        x = F.softmax
        x = self.fc2(x)
        return x</code></pre>
<p>실험군1 sigmoid 사용:</p>
<pre><code class="language-python">class Net_sigmoid(nn.Module):
    def __init__(self):
        super(Net_sigmoid,self).__init__()
        self.em = nn.Embedding(len(TEXT.vocab.stoi),embeding_dim)
        self.rnn = RNNCell_Encoder(embeding_dim,hidden_size)
        self.fc1 = nn.Linear(hidden_size,256)
        self.fc2 = nn.Linear(256,3)

    def forward(self,x):
        x = self.em(x)
        x = self.rnn(x)
        x = torch.sigmoid(self.fc1(x))
        x = self.fc2(x)
        return x</code></pre>
<p>실험군2 hyperbolic tangent 사용:</p>
<pre><code class="language-python">class Net_hyperbolic_tangent(nn.Module):
    def __init__(self):
        super(Net_hyperbolic_tangent,self).__init__()
        self.em = nn.Embedding(len(TEXT.vocab.stoi),embeding_dim)
        self.rnn = RNNCell_Encoder(embeding_dim,hidden_size)
        self.fc1 = nn.Linear(hidden_size,256)
        self.fc2 = nn.Linear(256,3)

    def forward(self,x):
        x = self.em(x)
        x = self.rnn(x)
        x = torch.tanh(self.fc1(x))
        x = self.fc2(x)
        return x</code></pre>
<p>실험군3 leaky ReLU 사용:</p>
<pre><code class="language-python">class Net_leaky_relu(nn.Module):
    def __init__(self):
        super(Net_leaky_relu,self).__init__()
        self.em = nn.Embedding(len(TEXT.vocab.stoi),embeding_dim)
        self.rnn = RNNCell_Encoder(embeding_dim,hidden_size)
        self.fc1 = nn.Linear(hidden_size,256)
        self.fc2 = nn.Linear(256,3)

    def forward(self,x):
        x = self.em(x)
        x = self.rnn(x)
        x = F.leaky_relu(self.fc1(x))
        x = self.fc2(x)
        return x</code></pre>
<p>optimizer:</p>
<pre><code class="language-python">loss_fn = nn.CrossEntropyLoss()

model = Net()
model.to(device)
optimizer = torch.optim.Adam(model.parameters(),lr=0.0001)

model_sigmoid = Net_sigmoid()
model_sigmoid.to(device)
optimizer_sigmoid = torch.optim.Adam(model_sigmoid.parameters(),lr=0.0001)

model_hyperbolic_tangent = Net_hyperbolic_tangent()
model_hyperbolic_tangent.to(device)
optimizer_hyperbolic_tangent = torch.optim.Adam(model_hyperbolic_tangent.parameters(),lr=0.0001)

model_leaky_relu = Net_leaky_relu()
model_leaky_relu.to(device)
optimizer_leaky_relu = torch.optim.Adam(model_leaky_relu.parameters(),lr=0.0001)

model_softmax = Net_softmax()
model_softmax.to(device)
optimizer_softmax = torch.optim.Adam(model_softmax.parameters(),lr=0.0001)</code></pre>
<p>실험 결과:</p>
<ol>
<li>ReLU 사용:
<img src="https://velog.velcdn.com/images/tree_jhk/post/60fc1b83-352f-49df-8b19-3c75a1d82030/image.png" alt=""></li>
</ol>
<ol start="2">
<li>sigmoid 사용:
<img src="https://velog.velcdn.com/images/tree_jhk/post/2eb4754e-d5ba-45ff-ab92-72531199cad6/image.png" alt=""></li>
</ol>
<ol start="3">
<li>hyperbolic tangent 사용:
<img src="https://velog.velcdn.com/images/tree_jhk/post/13badea3-b3b0-4bb4-8233-dca72f465362/image.png" alt=""></li>
</ol>
<ol start="4">
<li>leaky ReLU 사용:
<img src="https://velog.velcdn.com/images/tree_jhk/post/34242eb5-d79d-42b9-b438-b1f2cb0a0555/image.png" alt=""></li>
</ol>
<h3 id="실험-소감">실험 소감</h3>
<p>생각했던 것보다, IMDB 데이터셋의 경우, 활성화 함수를 바꾼다고 성능이 크게 바뀌지 않게 됐다.</p>
<p>결국 vanila RNN의 고질적인 문제인 단기 기억을 해결하기 위해 나처럼 많은 시도들을 했었던 것 같다. 결국 한계가 있었기 때문에 LSTM, GRU 같은 모델들을 개발한 것 같다.</p>
<p>다만, ReLU함수의 학습 속도가 제일 빠르다는 것을 확인할 수 있다. (약 1.246배 빨랐다)</p>
<h3 id="vanila-rnn-모델에-dropout-적용">vanila RNN 모델에 dropout 적용</h3>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/02e3fd3c-1b00-4fcd-9a3d-851aa2f7f9ec/image.png" alt=""></p>
<p>위와 같이 dropout은 <strong>신경망이 과적합되는 것을 방지</strong>하기 위해, <strong>학습 과정 중 일부 노드(뉴런)을 학습에서 제외</strong>시키는 방법이다.</p>
<p>내 예상에는, <strong>애초에 vanila RNN이 학습이 잘 안되기 때문에 dropout의 효과가 좀 무의미할 것 같다.</strong></p>
<pre><code class="language-python">class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.em = nn.Embedding(len(TEXT.vocab.stoi),embeding_dim)
        self.rnn = RNNCell_Encoder(embeding_dim,hidden_size)
        self.fc1 = nn.Linear(hidden_size,256)
        self.dropout1 = nn.Dropout(0.5)
        self.fc2 = nn.Linear(256,3)

    def forward(self,x):
        x = self.em(x)
        x = self.rnn(x)
        x = F.relu(self.fc1(x))
        x = self.dropout1(x)
        x = self.fc2(x)
        return x</code></pre>
<h3 id="dropout-적용결과">dropout 적용결과:</h3>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/9507240e-a119-4598-a811-e536b23bc18d/image.png" alt=""></p>
<p><strong>dropout을 적용하지 않을 때보다 확실한 장점이 있었다.</strong>
일부 노드들을 학습에서 제외시킴으로서, <strong>학습을 마치는데 소요되는 시간이 매우 줄었다.</strong> 3852초-&gt;750초 <strong>약 5배의 속도 차이가 발생했다.</strong>
확실하지는 않지만, <strong>5번째 epoch에서 51.2%로 정확도가 증가한 것처럼 보인다.</strong> 물론 test 데이터셋에서는 50.3%로 dropout을 적용하지 않을 때와 큰 차이가 없어보이지만 <strong>학습이 제대로 되는 LSTM 모델에서는 dropout이 큰 효과를 발휘할 것 같다.</strong></p>
<h3 id="lstm-모델에-dropout-적용-전">LSTM 모델에 dropout 적용 전</h3>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/83c8b383-1039-4e17-ae55-9ba9d9405bbd/image.png" alt="">
LSTM 모델을 사용하여 위와 같이, 재귀적으로 과거 정보들과 입력값을 함께 사용하여 장기 기억을 할 수 있게 된다.</p>
<p>같은 IMDB 데이터셋에 ReLU를 활성화 함수로 사용해서 성능이 향상되는지 확인해보겠다.
(추가할 예정)</p>
<h3 id="lstm-모델에-dropout-적용-후">LSTM 모델에 dropout 적용 후</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[뉴스 제목 감정 분석] 2편 [뉴스 제목 수집하기] 감정 분석 적용 BERT 사용]]></title>
            <link>https://velog.io/@tree_jhk/%EB%89%B4%EC%8A%A4-%EC%A0%9C%EB%AA%A9-%EA%B0%90%EC%A0%95-%EB%B6%84%EC%84%9D-2%ED%8E%B8-%EB%89%B4%EC%8A%A4-%EC%A0%9C%EB%AA%A9-%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0-%EA%B0%90%EC%A0%95-%EB%B6%84%EC%84%9D-%EC%A0%81%EC%9A%A9-BERT%EC%99%80-finBERT-%EC%82%AC%EC%9A%A9</link>
            <guid>https://velog.io/@tree_jhk/%EB%89%B4%EC%8A%A4-%EC%A0%9C%EB%AA%A9-%EA%B0%90%EC%A0%95-%EB%B6%84%EC%84%9D-2%ED%8E%B8-%EB%89%B4%EC%8A%A4-%EC%A0%9C%EB%AA%A9-%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0-%EA%B0%90%EC%A0%95-%EB%B6%84%EC%84%9D-%EC%A0%81%EC%9A%A9-BERT%EC%99%80-finBERT-%EC%82%AC%EC%9A%A9</guid>
            <pubDate>Tue, 28 Jun 2022 12:48:12 GMT</pubDate>
            <description><![CDATA[<p>이번 포스트에서는, 지난 번 포스트에 이어서, 감정 분석을 적용한 데이터셋을 만들겠습니다.
판다스의 dataframe 형식으로 저장도 하고 csv형식으로 최종 저장하겠습니다.
BERT를 사용할 것이고 공개된 pre-trained 모델을 사용합니다.</p>
<p>또한 추후에 비트코인 가격을 추가할 열을 dataframe에 추가하겠습니다.</p>
<p>지난 번 포스트에서 만든 함수를 그대로 사용해서 만듭니다.
지난 번 포스트 링크: <a href="https://velog.io/@tree_jhk/%EB%89%B4%EC%8A%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%88%98%EC%A7%91-%EB%B0%8F-%EC%A0%84%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-1-%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0">[뉴스 제목 감정 분석] 1편 [뉴스 제목 수집하기] 크롤링</a></p>
<p>자세한 코드 및 자세한 주석은 제 깃허브에 올렸습니다. 링크: <a href="https://github.com/tree-jhk/get_bitcoinprice_news_data_with_sentiment_analysis/blob/main/get_data.ipynb">소스코드</a></p>
<h3 id="1-import">1. import</h3>
<pre><code class="language-python"># 감정 분석에 쓸 도구 구성하기 입니다.
import pandas as pd
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
tokenizer = AutoTokenizer.from_pretrained(&#39;nlptown/bert-base-multilingual-uncased-sentiment&#39;)
model = AutoModelForSequenceClassification.from_pretrained(&#39;nlptown/bert-base-multilingual-uncased-sentiment&#39;)

# 입력: string: 감정 분석하고자 하는 문장
# 출력: 감정 분석 결과 1~5 -&gt; 클수록 긍정적인 문장
def get_sentiment(string:str):
    tokens = tokenizer.encode(string,return_tensors=&#39;pt&#39;)
    result = model(tokens)
    return (int(torch.argmax(result.logits)) + 1)</code></pre>
<h3 id="2-dataframe-구성하기">2. Dataframe 구성하기</h3>
<pre><code class="language-python">news_sentiment_analysis = pd.DataFrame({&#39;Date&#39;:[],&#39;News title&#39;:[],&#39;Bitcoin price&#39;:[],&#39;Sentiment&#39;:[]})
</code></pre>
<h3 id="3-완성하기">3. 완성하기</h3>
<p>위의 get_sentiment 함수를 이용해서
데이터프레임을 완성해보겠습니다.</p>
<pre><code class="language-python">for i,(date,news_titles) in enumerate(news_date_title_dictionary.items()):
    for j,n_t in enumerate(news_titles):
        sentiment = get_sentiment(n_t)
        news_sentiment_analysis.loc[i+j] = [date,n_t,0,sentiment]
display(news_sentiment_analysis)</code></pre>
<h3 id="4-출력-결과">4. 출력 결과</h3>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/54af89ae-518a-4225-9578-a26a1af90850/image.png" alt=""></p>
<h3 id="5-다음-포스트">5. 다음 포스트</h3>
<ol>
<li>비트코인 가격까지 추가</li>
<li>방대한 양의 데이터셋을 구성하기 위해, fastAPI의 비동기식 처리를 이용해서 빠른 데이터 수집을 할 예정</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 같은데 다르다고 인식되는 경우]]></title>
            <link>https://velog.io/@tree_jhk/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%82%B4%EC%9A%A9%EC%9D%B4-%EA%B0%99%EC%9D%80%EB%8D%B0-%EB%8B%A4%EB%A5%B4%EB%8B%A4%EA%B3%A0-%EC%9D%B8%EC%8B%9D%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0</link>
            <guid>https://velog.io/@tree_jhk/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%82%B4%EC%9A%A9%EC%9D%B4-%EA%B0%99%EC%9D%80%EB%8D%B0-%EB%8B%A4%EB%A5%B4%EB%8B%A4%EA%B3%A0-%EC%9D%B8%EC%8B%9D%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0</guid>
            <pubDate>Sun, 26 Jun 2022 10:43:08 GMT</pubDate>
            <description><![CDATA[<p>뉴스 기사 크롤링 중, 원하는 기사 날짜가 아닐 경우에는 받지 않을려고 했습니다.
그래서 시도한 결과 이상한 점을 발견했는데요.
<img src="https://velog.velcdn.com/images/tree_jhk/post/ce2149e2-5e3e-409d-b7da-c4acbb6dbdcb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/db69a0c5-5680-437f-9a74-c502e284308c/image.png" alt="">
다르다면서, 눈으로 보기에는 완전히 같은 것처럼 보입니다.</p>
<p>이를 해결하기 위해 <strong>2가지를 확인</strong>해야 합니다.
<strong>1. 문자열의 길이는 같은지?</strong>
<img src="https://velog.velcdn.com/images/tree_jhk/post/eb5225f1-344e-49dd-bd8a-36ae36bd9ee5/image.png" alt="">
<img src="https://velog.velcdn.com/images/tree_jhk/post/659351a7-1fb5-4e4b-a5ba-1c706e3e5df7/image.png" alt=""></p>
<p>출력 결과 길이는 같으므로, 2번이 의심됩니다.</p>
<ol start="2">
<li><p><strong>인코딩 결과가 다른지? (크롤링 중에 종종 발생합니다.)</strong></p>
<p>저는 <strong>Visual Studio Code로 작업</strong>을 하고, <strong>UTF-8 로 인코딩</strong>합니다.
크롤링한 사이트에서 <strong>특수문자(공백,특수문자들 등등)의 인코딩 형식이 다를 수 있습니다.</strong>
<strong>date_string 과 &#39; - Jun 16, 2022&#39; 의 인코딩 결과를 UTF-8형식으로 비교</strong>해보겠습니다.
<img src="https://velog.velcdn.com/images/tree_jhk/post/bb49dffd-8509-4ceb-b89f-a2e452d6cb14/image.png" alt=""></p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/159ed890-dac3-463d-926b-b94ead4e94c4/image.png" alt=""></p>
<p>인코딩 결과가 다른 것을 알게 됐습니다. &#39;Jun&#39; 이후부터는 동일하므로, &#39; - &#39; 부분 이후부터를 슬라이싱으로 받아서 비교해보겠습니다.</p>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/2895d168-3ce8-40e1-8699-df94b18c054c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/f63fb75b-0df0-4644-aa58-6a7bebdc8e17/image.png" alt=""></p>
<p>same이 떴네요 해결했습니다~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022년 여름방학 목표!]]></title>
            <link>https://velog.io/@tree_jhk/2022%EB%85%84-%EC%97%AC%EB%A6%84%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C</link>
            <guid>https://velog.io/@tree_jhk/2022%EB%85%84-%EC%97%AC%EB%A6%84%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C</guid>
            <pubDate>Sun, 19 Jun 2022 15:48:41 GMT</pubDate>
            <description><![CDATA[<h2 id="1-naver-clova-ai-rush-2022-2라운드-진출하기">1. NAVER CLOVA AI RUSH 2022 2라운드 진출하기</h2>
<p>-&gt; 파이썬 머신러닝 완벽 가이드 빠르게 완강하기
-&gt; 컴퓨터비전, NLP, 추천시스템 각각 하나씩 맛보기 (1라운드 시작 전까지)
-&gt; 1라운드: NLP 과제 하나 해결하기 == Apollo Data Dev의 [엉터리 문서 검출]
-&gt; 2라운드 진출한다면: 추천 시스템 과제 하나 해결하기 == CLOVA ML X의 [대규모 쇼핑 데이터를 활용한 일반적인 유저 임베딩 추출]</p>
<h2 id="2-한이음---뉴스-기사의-감정분석을-통한-비트코인-주식-가격-예측하기">2. 한이음 - 뉴스 기사의 감정분석을 통한 비트코인 주식 가격 예측하기</h2>
<p>-&gt; 데이터 전처리 완료하기
-&gt; 모델링 완성하기
-&gt; NLP 강의 완강하기
-&gt; 주가 예측 관련 강의 완강하기</p>
<h2 id="3-naver-부스트캠프-ai-tech-합격을-위한-코딩테스트-준비">3. NAVER 부스트캠프 AI Tech 합격을 위한 코딩테스트 준비</h2>
<p>우선순위 알고리즘:
(기준: 백준 + 풀이 횟수 2000회 이상 + 구글링해서 해답이 있어야함):</p>
<h4 id="필수-유형">[필수 유형]</h4>
<p>필수 유형: (기본 구현 및 기본 자료구조들 문제 풀이) + (비트 마스킹, 누적합, dp: 실버4 수준의 문제까지) + (프로그래머스 레벨 1 전체)</p>
<h4 id="1단계부터-5단계까지-차례대로-풀어보자">[1단계부터 5단계까지 차례대로 풀어보자]</h4>
<p>1단계: (DFS/BFS, 백트래킹, 삼성 시뮬레이션 유형: 골드3 수준의 문제까지)
2단계: (이진 탐색: 골드3 수준의 문제까지)
3단계: (투포인터 누적합 슬라이딩윈도우: 골드3 수준의 문제까지)
4단계: (다익스트라 플로이드워셜: 골드4 수준의 문제까지)
5단계: (DP: 골드3 수준의 문제까지)</p>
<h4 id="1단계5단계-진행하면서-할-일">[1단계~5단계 진행하면서 할 일]</h4>
<p>(삼성 시뮬레이션 유형 골드3 수준의 문제까지 + 프로그래머스 레벨2 전체 + 프로그래머스 레벨2 오답 다시 풀기 + 프로그래머스 레벨3 일부)</p>
<p>나중에 공부해볼 알고리즘들: 벨만포드, 위상정렬 최소신장트리 유니온파인드, 세그먼트 트리, 분할 정복, 비트마스킹</p>
<p>-&gt; 프로그래머스 레벨2 모든 문제 풀기 (다시 풀기까지)
-&gt; 빡구현 유형, DFS/BFS 유형, DP 유형, 이분 탐색 유형, 투 포인터 유형, 누적 합 유형, 최단경로 유형들 익히기</p>
<h2 id="4-토익-950점-이상-받기">4. 토익 950점 이상 받기</h2>
<p>-&gt; 영단어책 진짜 달달 외우기
-&gt; 문제 많이 풀면서 실력 키우기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[NAVER CLOVA AI RUSH 2022 코딩테스트 후기]]></title>
            <link>https://velog.io/@tree_jhk/NAVER-CLOVA-AI-RUSH-2022-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/NAVER-CLOVA-AI-RUSH-2022-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sun, 19 Jun 2022 15:37:13 GMT</pubDate>
            <description><![CDATA[<p>학교 선배님이 CLOVA AI RUSH 2022을 알려주셔서 이번에 지원하게 됐는데 정말 운 좋게도 선발됐다. 꼭 참가하고 싶었던 대회였고 AI 분야에서 나의 첫 합격이라서 매우 기뻤다. 이 대회를 참여해보라고 권유해주신 학교 선배님한테 정말 감사하다!</p>
<p><img src="https://velog.velcdn.com/images/tree_jhk/post/d3d956d7-6f1b-4379-8427-c4285ef706a8/image.png" alt=""></p>
<p>코딩테스트 문제는 <strong>총 4문제</strong>가 출제됐고 그 중 <strong>2문제를 풀고 선발</strong>됐다.</p>
<p><strong>총 2시간</strong>이 주어졌고, <strong>Python</strong>으로 풀었다.</p>
<p><strong>1번 문제:</strong>
난이도: 백준 실버2~실버1 -&gt; Solved
완전탐색 + 구현 문제였다.
지문도 길고 복잡해보여서 꽤나 헤맸다. 푸는데 1시간 정도 소요됐다.</p>
<p><strong>2번 문제:</strong>
난이도: 최소 백준 골드5 이상 -&gt; Unsolved
문자열 + 구현 문제였다.
지문이 길고 잘 이해가 안가서 3번 문제로 넘어갔다. 1번 문제보다 어려운 상황이었던 것 같다.</p>
<p><strong>3번 문제:</strong>
난이도: 백준 브론즈2~실버5 -&gt; Solved
구현 문제였다.
쉬운 구현 문제였다. 푸는데 30분 정도 소요됐다.</p>
<p><strong>4번 문제:</strong>
난이도: 최소 백준 골드3 이상 -&gt; Unsolved
DFS/BFS인 것으로 추정한다.
지문이 매우 복잡해보이는데 시간이 촉박해서 풀 생각조차 하지 못했다.</p>
<p>1번 문제와 3번 문제를 풀고 시간이 남아서 여러 가지 테스트 케이스를 혼자 만들어서 적용해서 적용되지 않는 사례는 없는지 코드가 제대로 작동하는지 꼼꼼하게 풀려고 했었다. 기본적인 테스트케이스만 주어지기 때문에 꼼꼼하게 풀 필요가 있어 보였다.</p>
<p>이번 코딩테스트의 합격 커트라인은 2솔인 것 같다. 2솔이어도 합격하지 못한 케이스도 있었다고 한다.</p>
<p>1라운드 대회가 끝나고 1라운드 후기도 작성해봐야겠다.</p>
<p>내 첫 코딩테스트 합격이라서 매우 기쁜 합격이었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[뉴스 제목 감정 분석] 1편 [뉴스 제목 수집하기] 크롤링]]></title>
            <link>https://velog.io/@tree_jhk/%EB%89%B4%EC%8A%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%88%98%EC%A7%91-%EB%B0%8F-%EC%A0%84%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-1-%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/%EB%89%B4%EC%8A%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%88%98%EC%A7%91-%EB%B0%8F-%EC%A0%84%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-1-%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 19 May 2022 09:55:56 GMT</pubDate>
            <description><![CDATA[<h1 id="수집한-데이터">수집한 데이터</h1>
<p>수집한 데이터: investing.com에서 BTC 종목에 대한 뉴스 제목들
수집한 사이트: <a href="https://www.investing.com/crypto/bitcoin/news/2">investing.com BTC 뉴스</a></p>
<p>참고로 url에서
<a href="https://www.investing.com/crypto/bitcoin/news/2">https://www.investing.com/crypto/bitcoin/news/2</a>
맨 끝의 &#39;2&#39;에 잠깐 주목해주시고 이제 잊어도 됩니다.</p>
<p>우선 뉴스 제목을 한 페이지만 수집해보고, <strong>여러 페이지의 뉴스 제목들도 수집해보겠습니다.</strong></p>
<p>사용 라이브러리:
import requests
from bs4 import BeautifulSoup</p>
<h1 id="수집-과정">수집 과정</h1>
<h2 id="뉴스-제목-한-페이지만-수집하기">뉴스 제목 한 페이지만 수집하기</h2>
<h3 id="1-목표-데이터-정하기">1. 목표 데이터 정하기</h3>
<p>저는 이번에 목표 데이터로, investing.com 홈페이지에서 BTC 종목에 대한 뉴스들의 제목을 수집하려고 했습니다.
<img src="https://velog.velcdn.com/images/tree_jhk/post/3e08f38c-43bf-436a-b9ae-7bcea73742f8/image.png" alt="">
해당 사이트에서 news 카테고리를 따로 클릭하면
<a href="https://www.investing.com/crypto/bitcoin/news/2">investing.com BTC 뉴스</a> 사이트가 실행됩니다.
해당 페이지에서 뉴스 제목들만 가져오는 것이 목표입니다.
<img src="https://velog.velcdn.com/images/tree_jhk/post/b6852379-68ce-4dd7-b204-bf9afcde9f99/image.png" alt=""></p>
<h3 id="2-크롤링-설정-세팅하기">2. 크롤링 설정 세팅하기</h3>
<p>아래와 같이 url 문자열과 headers를 작성해주시고, beautifulsoup과 requests를 import해서 크롤링 기초 세팅을 합니다.
headers는 복사붙여넣기 하시면 됩니다!</p>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

# html 정보 가져오기 및 headers 세팅
headers = {&#39;user-agent&#39;:&#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36&#39;,
            &#39;accept&#39;:&#39;text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&#39;}
# 뉴스 제목 url
url = &quot;https://www.investing.com/crypto/bitcoin/news&quot;
# http 요청 받기
response = requests.get(url,headers=headers)
# url에 대한 정보를 받을 수 있는 soup 생성
soup = BeautifulSoup(response.text,&#39;lxml&#39;)</code></pre>
<h3 id="3-뉴스-제목에-대한-html-정보-파악하기">3. 뉴스 제목에 대한 html 정보 파악하기</h3>
<ol>
<li><a href="https://www.investing.com/crypto/bitcoin/news">뉴스사이트</a>에 접속합니다.</li>
<li>F12 눌러서 빨간 동그라미 표시 부분 클릭하고 뉴스 제목을 클릭하면 뉴스 제목에 대한 html 정보를 알 수 있습니다.<img src="https://velog.velcdn.com/images/tree_jhk/post/fa00ada4-5ebd-4481-83d5-1931bb16c2dd/image.png" alt=""></li>
<li>class=&#39;title&#39; 임을 알 수 있습니다.<img src="https://velog.velcdn.com/images/tree_jhk/post/368e51c3-a2e8-451e-b263-980e4d4f0982/image.png" alt=""></li>
</ol>
<h3 id="4-첫-페이지의-뉴스-제목-수집하기">4. 첫 페이지의 뉴스 제목 수집하기</h3>
<p>3번에서 파악한 뉴스 제목의 html 정보를 기반으로 첫 페이지의 뉴스 제목을 수집해보겠습니다.
파이썬의 리스트 컴프리헨션 기법을 사용해서 다음 코드를 추가하면 끝입니다.
news_title  리스트에는 해당 페이지의 뉴스 제목들의 문자열이 담겨져 있게 됩니다.</p>
<h4 id="주목할-점은-soupselecttitle-이-아니라-soupselecttitle-입니다-에-주의하세요">주목할 점은 soup.select(&#39;title&#39;) 이 아니라 soup.select(&#39;.title&#39;) 입니다. &#39;.&#39;에 주의하세요.</h4>
<pre><code class="language-python">news_title=[title.get(&#39;title&#39;) for title in soup.select(&#39;.title&#39;)]</code></pre>
<h3 id="5-임시-출력-결과">5. 임시 출력 결과</h3>
<p>아래 사진처럼, 뭔가 none이 껴있네요.
아마도 soup.select(&#39;.title&#39;)을 하면서,
이름이 중복되는 다른 html 요소랑 겹쳐서 이와 같이 나오는 것 같습니다.
none을 없애는 코드도 추가하죠.
<img src="https://velog.velcdn.com/images/tree_jhk/post/38bc783d-5a6b-46f2-a00a-0af38d70b517/image.png" alt=""></p>
<p>none 을 처리하는 코드입니다.</p>
<pre><code class="language-python">news_title=[title.get(&#39;title&#39;) for title in soup.select(&#39;.title&#39;) if title.get(&#39;title&#39;) != None]</code></pre>
<h3 id="6-최종-코드-및-최종-출력-결과">6. 최종 코드 및 최종 출력 결과</h3>
<p>최종 코드:</p>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

# html 정보 가져오기 및 headers 세팅
headers = {&#39;user-agent&#39;:&#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36&#39;,
            &#39;accept&#39;:&#39;text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&#39;}
# 뉴스 제목 url
url = &quot;https://www.investing.com/crypto/bitcoin/news&quot;
# http 요청 받기
response = requests.get(url,headers=headers)
# url에 대한 정보를 받을 수 있는 soup 생성
soup = BeautifulSoup(response.text,&#39;lxml&#39;)

news_title=[title.get(&#39;title&#39;) for title in soup.select(&#39;.title&#39;) if title.get(&#39;title&#39;) != None]
print(news_title)</code></pre>
<p>출력 결과:
none이 좀 많았던 것 같습니다.
<img src="https://velog.velcdn.com/images/tree_jhk/post/de549230-3fc2-4ec7-a46a-2b7019a7c3d0/image.png" alt=""></p>
<h2 id="뉴스-제목-여러-페이지만-수집하기">뉴스 제목 여러 페이지만 수집하기</h2>
<h3 id="1-목표-데이터-정하기-1">1. 목표 데이터 정하기</h3>
<p>이번에는 2022년 3월 15일부터 2022년 6월 15일까지의 뉴스 제목들을 수집해보겠습니다.
<img src="https://velog.velcdn.com/images/tree_jhk/post/ee5bc0a4-6c28-48a5-923d-2578dfa5a8c9/image.png" alt=""></p>
<p>2022년 6월 26일 기준으로, 18페이지에서부터 6월 15일 뉴스 제목이 등장했습니다. 3월 14일 날짜가 발견되면 break하는 형식으로 수집해보겠습니다.</p>
<h3 id="2-크롤링-설정-및-기초-코드">2. 크롤링 설정 및 기초 코드</h3>
<pre><code class="language-python"># html 정보 가져오기 및 headers 세팅
headers = {&#39;user-agent&#39;:&#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36&#39;,
            &#39;accept&#39;:&#39;text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&#39;}

def get_url_info(iter):
    if iter==1:
        url = &quot;https://www.investing.com/crypto/bitcoin/news&quot;
    else:
        url = f&quot;https://www.investing.com/crypto/bitcoin/news/{iter}&quot;
    response = requests.get(url,headers=headers)
    return BeautifulSoup(response.text,&#39;lxml&#39;)

import requests
from bs4 import BeautifulSoup
import re

# 종료시키는 finish bool형 변수
finish=False

for iter in range(18,99999):
    soup = get_url_info(iter)
    news_title_list, news_date_list=[], []
    for i,title in enumerate(soup.select(&quot;.title&quot;)):
        title_string = title.get(&#39;title&#39;)
        if title_string != None:
            print(i,title_string,sep=&#39; &#39;)
    print(&#39;\n&#39;)</code></pre>
<p>위 코드의 결과:
<img src="https://velog.velcdn.com/images/tree_jhk/post/54766c91-9adc-49d0-8b41-666c1bbfae20/image.png" alt="">
이 사이트 뉴스 기사 크롤링할 때마다 이상한 점이, 0~13까지의 인덱스의 뉴스 기사들은 none이거나 다른 기사랑 중복됐습니다. 중복을 피하기 위해 인덱스 번호가 14 이상일 때만 수집해야겠습니다.
<strong>따라서 크롤링 조건이 두 가지입니다.</strong></p>
<ol>
<li>enumerate를 통한 반복문에서 인덱스 번호가 14이상일 때 저장한다.</li>
<li>none이 아닐 때만 저장한다.</li>
</ol>
<p><strong>최종적으로 완성할 함수는 다음의 매개변수를 갖습니다.</strong></p>
<ol>
<li>수집할 마지막 날짜를 포함하는 페이지의 번호를 매개변수로 갖는다.</li>
<li>포함시킬 날짜의 제일 과거 날짜의 전날을 &#39;Mar 14, 2022&#39;형식으로 입력합니다.</li>
<li>크롤링할 첫 페이지에 원하지 않는 날짜가 포함하지 않기 위해, 포함시킬 날짜의 마지막 날짜의 바로 다음 날을 &#39;Jun 16, 2022&#39;형식으로 입력합니다.</li>
</ol>
<p>완성 코드입니다:</p>
<pre><code class="language-python"># html 정보 가져오기 및 headers 세팅
headers = {&#39;user-agent&#39;:&#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36&#39;,
            &#39;accept&#39;:&#39;text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&#39;}

def get_url_info(iter):
    if iter==1:
        url = &quot;https://www.investing.com/crypto/bitcoin/news&quot;
    else:
        url = f&quot;https://www.investing.com/crypto/bitcoin/news/{iter}&quot;
    response = requests.get(url,headers=headers)
    return BeautifulSoup(response.text,&#39;lxml&#39;)

import requests
from bs4 import BeautifulSoup

def get_news_data_with_date(page_number:int,first_date:str,exculde_date:str):
    date_error = &#39;\nERROR: Date is not in proper form.\n&#39;
    month = [&#39;Jan&#39;,&#39;Feb&#39;,&#39;Mar&#39;,&#39;Apr&#39;,&#39;May&#39;,&#39;Jun&#39;,&#39;Jul&#39;,&#39;Aug&#39;,&#39;Sep&#39;,&#39;Oct&#39;,&#39;Nov&#39;,&#39;Dec&#39;]
    if first_date[:3] not in month or exculde_date[:3] not in month:
        print(date_error)
        return {}
    elif len(first_date) != 12 or first_date[3] != &#39; &#39; or first_date[6:8] != &#39;, &#39; or len(exculde_date) != 12 or exculde_date[3] != &#39; &#39; or exculde_date[6:8] != &#39;, &#39;:
        print(date_error)
        return {}

    finish=False
    news_date_title_dictionary = {}

    for page_num in range(page_number,9999999999):
        soup = get_url_info(page_num)
        news_title_list, news_date_list=[], []
        for i,title in enumerate(soup.select(&quot;.title&quot;)):
            title_string = title.get(&#39;title&#39;)
            if title_string != None:
                news_title_list.append(title_string)
        for date in soup.select(&quot;.date&quot;):
            date_string = str(date.get_text())
            if exculde_date != date_string[3:]:
                if (first_date) == date_string[3:]:
                    finish = True
                else:
                    news_date_list.append(date_string)

        for date, title in zip(news_date_list, news_title_list):
            if date in news_date_title_dictionary:
                news_date_title_dictionary[date].append(title)
            else:
                news_date_title_dictionary[date]=[title]
        if finish:
            break
    return news_date_title_dictionary

news_date_title_dictionary = get_news_data_with_date(18,&#39;Mar 14, 2022&#39;,&#39;Jun 16, 2022&#39;)

f = open(&#39;nlp_preprocessing.txt&#39;,&#39;w&#39;,-1, &#39;utf-8&#39;)
for date,title in news_date_title_dictionary.items():
    f.write(f&quot;기사 작성 날짜:{date}\n기사 제목들:{title}\n\n&quot;)
f.close</code></pre>
<p>최종적으로 완성한 결과물을 txt형식으로 저장합니다.
결과물을 깃허브에 올렸습니다.
<a href="https://github.com/tree-jhk/get_bitcoinprice_news_data_with_sentiment_analysis/blob/main/bitcoin_news_2022_Mar_15_2022_Jun_15.txt">https://github.com/tree-jhk/get_bitcoinprice_news_data_with_sentiment_analysis/blob/main/bitcoin_news_2022_Mar_15_2022_Jun_15.txt</a></p>
<h2 id="다음-포스트">다음 포스트</h2>
<p>2 - 작성 날짜 받아오기
3 - 여러 작성 날짜 - 뉴스 제목 딕셔너리로 이어주기
4 - 뉴스 제목 전처리해주기(소문자 만들기, 특수문자 제거, 무의미한 한 글자 제거) 정규식을 통해
5 - 비트코인 날짜별 종가 정보 받아오고, 여러 작성 날짜 - 뉴스 제목 - 비트코인 날짜별 종가 정보 로 최종 데이터 완성하기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SPARO LAB 동계학부연구생 후기]]></title>
            <link>https://velog.io/@tree_jhk/SPARO-LAB-%EB%8F%99%EA%B3%84%ED%95%99%EB%B6%80%EC%97%B0%EA%B5%AC%EC%83%9D-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/SPARO-LAB-%EB%8F%99%EA%B3%84%ED%95%99%EB%B6%80%EC%97%B0%EA%B5%AC%EC%83%9D-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Wed, 27 Apr 2022 07:18:29 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tree_jhk/post/8ef3a152-d227-442d-b7c6-373ff3a82529/image.png" alt=""></p>
<p>결론부터 말하자면,</p>
<h4 id="나의-진로를-정하는데-많은-도움이-됐던-매우-좋은-경험이었다"><strong>나의 진로를 정하는데 많은 도움이 됐던 매우 좋은 경험이었다.</strong></h4>
<p>SPARO Lab 자체도 매우 좋았고, 학부연구생 프로그램 자체로부터도 배운 것이 많았다.
그래서 후기를 작성하게 됐다. <del>(참고: 들여쓰기가 안됨...)</del></p>
<h2 id="연구실-소개">연구실 소개</h2>
<p>연구실 이름: 인하대학교 SPARO Lab (Spatial AI and Robotics Lab)
지도교수님: 인하대학교 전기공학과 조영근 교수님
연구 분야: Visual SLAM, Lidar SLAM, Robust Sensing, Visual Mapping, Lidar Mapping 등
연구실 웹사이트: <a href="https://sites.google.com/view/sparo">SPARO Lab</a>
학부연구생 활동 기간: 2021년 12월~2022년 3월<img src="https://velog.velcdn.com/images/tree_jhk/post/b36235c8-5f47-4b40-baf9-e06b6c9fcfee/image.png" alt=""></p>
<h2 id="sparo-lab에서의-학부연구생-프로젝트를-추천하는-이유">SPARO Lab에서의 학부연구생 프로젝트를 추천하는 이유</h2>
<ol>
<li><p><strong>구성원들이 좋다.</strong></p>
<p>학부연구생 프로그램이라서, 대학원 체험판 느낌이긴 하지만, 3개월 동안 내가 재밌어서, 연구실을 자주 들려서 프로젝트를 계속 진행했다.</p>
</li>
</ol>
<p>** 공부는 어렵고 연구는 즐겁게 할 수 있었는데, 이것은 구성원들의 성격이 좋아서 가능했다고 생각이 든다.**
 석사의 경우, 2년 동안 같은 연구실에서 같은 팀원들과 지낼텐데, 그 팀원들이랑 안 맞으면, 안 그래도 고될 수 있는 연구가, 진짜 많이 힘들어질 것 같다. <strong>하지만 SPARO 연구실 구성원들은 다들 정말 유쾌하다.</strong>
 또한 나는 3학년 올라가는 학부생이어서 교수님과 나보다 선배들한테 가까운 미래에 대한 조언들을 들을 수 있었다. 그리고 구성원들이 유쾌하다보니까 연구실에 오래 있어도 시간이 금방 간다.</p>
<ol start="2">
<li><p>교수님이 좋다.</p>
<p>학교에서 주관하는 INSTAR 동계 학부연구생 프로그램은 교수님들이 프로그램을 구성해서 자체적으로 진행을 하시는 것 같다.
조영근 교수님은 초반에 <strong>SLAM 관련 전체적인 기초지식들을 가르쳐주시고 터틀봇, 카메라,라이다를을 통한 실습</strong>을 하게 하셨다. 동계 방학의 바쁜 와중에도 학부생들을 대상으로 개인적으로 수업을 진행하시는게 굉장히 감사했다.
방학 중에 정기적으로 수업을 진행하셨고, 프로젝트를 진행할 때는 잘 안되는 것이 있으면 직접 도와주시기도 하셨다. 매주 교수님이 프로젝트 진행 관련해서 피드백을 주시면서 자료도 챙겨주셨다.
이렇게 교수님 덕분에 로봇학회 학술대회에 프로젝트에 대한 논문을 제출할 수 있었다. 교수님이 바쁘실텐데 지속적으로 많이 도와주셨던 것이 정말 좋았다.</p>
</li>
</ol>
<h2 id="연구실-환경">연구실 환경</h2>
<ol>
<li>연구실 장비들이 모두 최신형이고, 연구실 내부에 있는 서버 컴퓨터가 성능이 아주 대단하다. RAM 용량이 200기가바이트인 것은 난생 처음 봤다.</li>
<li>여러 고성능 SLAM 관련 장비들이 있어서, 실습하는 데에 아주 좋을 것이다.</li>
<li>교수님이 SLAM 관련 소프트웨어들을 많이 가지고 계셔서 실습하는 데에 좋을 것이다.</li>
<li>인하대학교 하이테크 건물에 위치해서, 인하대 후문가에 접근이 매우 쉽다. 따라서 식사하기가 매우 편하다.</li>
</ol>
<h2 id="학부연구생하면서-얻게-된-점">학부연구생하면서 얻게 된 점</h2>
<ol>
<li><p>시야가 넓어졌다.</p>
<p> 4학년이면 모를까, 1, 2, 3학년은 사실 과학기술에 대해 아는 것이 제한적일 것이라고 생각한다. 적어도 나는 그랬었다. 그러나 이번 동계학부연구생을 진행하면서, AI 관련해서 전반적인 지식들과 SLAM 분야의 지식들을 개략적으로 넓고 얕게 보고 들을 수 있는 기회였다. 견문을 넓히기 좋은 기회인 것 같다.
 나의 경우, 학부연구생의 AI프로젝트를 진행할 때, 머신러닝 모델의 개발과 시스템 개발의 과정 중에서 효율성과 성능 향상을 높이는 부분에 흥미를 느끼게 됐는데, 나중에 알고보니 이런 부분들이 [머신러닝 엔지니어]가 하는 역할인 것을 알게 됐다.
 프로젝트를 진행하면서 좀 더, 자동적으로 학습을 최적화하고 머신러닝 모델을 서빙을 하는 분야에 관심이 생겼다. 또한 관련 분야인 MLops 또는 ML엔지니어를 가까운 미래에 내가 희망하는 직무로 결정하게 됐다.
 만약 내가 학부연구생을 안했다면, 머신러닝 엔지니어링이라는 분야를 내가 흥미 있어 할지 몰랐을 것 같다.</p>
</li>
<li><p>의사소통이나 발표의 역량을 키울 수 있었다.</p>
<p>프로젝트를 진행하다보면, 내 생각을 상대방에게 정확하고 논리적으로 어느 정도의 기승전결을 고려해서 전달해야하는데, 이 부분을 신경쓰고 말을 하려고 하니까 의사소통 역량이 커졌다. 또한, 질문을 할 때도 &#39;A가 뭔가요?&#39;보다 구체적으로 내가 뭘 모르고 내가 왜 질문을 했고 어느 정도 알고 있고 이러한 정보들과 함께 질문하는 연습이 되었다. 덕분에 정확한 질문을 할 수 있는 역량을 기를 수 있었다.
동계 학부연구생 프로젝트를 하다보면, 각자 공부한 것이나 프로젝트 진행에 대해서 발표를 해야할 때가 있다. 나의 경우, 발표를 할수록 더 자연스럽게 청중에게 말을 전달하는 방법을 깨달아 갔다.</p>
<p>학부연구생을 하게 된다면, 열심히 참여해서 인사이트를 많이 얻어가면 좋은 것 같다!</p>
</li>
</ol>
<h2 id="진행했던-프로젝트">진행했던 프로젝트</h2>
<p><strong>[도로 환경에서 Semantic Segmentation 및 
Inverse Perspective Mapping 을 통한 주행영역 검출 방법]</strong> 라는 주제로 프로젝트를 진행했고, 프로젝트를 기반으로 로봇학회 학술대회에 참가했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2학년 겨울방학 목표 결과(일기장ㅋㅋ)]]></title>
            <link>https://velog.io/@tree_jhk/%EA%B2%A8%EC%9A%B8%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C-%EA%B2%B0%EA%B3%BC%EC%9D%BC%EA%B8%B0%EC%9E%A5%E3%85%8B%E3%85%8B</link>
            <guid>https://velog.io/@tree_jhk/%EA%B2%A8%EC%9A%B8%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C-%EA%B2%B0%EA%B3%BC%EC%9D%BC%EA%B8%B0%EC%9E%A5%E3%85%8B%E3%85%8B</guid>
            <pubDate>Tue, 01 Mar 2022 19:39:09 GMT</pubDate>
            <description><![CDATA[<p>이 블로그의 첫 글로, 링크: <a href="https://velog.io/@tree_jhk/%EC%9D%B4%EB%B2%88-%EA%B2%A8%EC%9A%B8%EB%B0%A9%ED%95%99-%EB%AA%A9%ED%91%9C">[2021년 겨울방학 목표!]</a> 
글을 작성했었고 3학년 1학기 시작된 이 시점에서 생각난 김에 달성 결과를 적어봄!</p>
<p><img src="https://images.velog.io/images/tree_jhk/post/b5972f19-fb22-452d-a783-c1838ffe8144/image.png" alt=""></p>
<h1 id="1번-목표">1번 목표</h1>
<p><img src="https://images.velog.io/images/tree_jhk/post/ae61d6ad-4ea4-4a73-bd13-aa678cfa7de0/image.png" alt="">
(학부연구생 프로젝트 결과의 한 장면입니다!)
1번 목표는 아마도(?) 간단한 논문 작성해서 제17회 한국로봇종합학술대회에 참가할 것으로 보아서, 성공이 예정되어 있다!
부족함이 많지만 그래도 프로젝트 결과물이 나오긴 해서 다행이다.
이번 학부연구생 진행하면서 넓고 얕게 지식들을 많이 알게 되서 좋았다. 자세한 건 나중에 포스팅을 하면서 정리를 좀 해놓아야겠다.</p>
<h1 id="2번-목표">2번 목표</h1>
<p>2번 목표는 그냥 안했다 ㅋㅋㅋ 귀찮았고 더 중요한 것들이 많았다.</p>
<h1 id="3번-목표">3번 목표</h1>
<p><img src="https://images.velog.io/images/tree_jhk/post/b7cf71fb-73d5-460f-9f0f-d12834e38ad5/image.png" alt="">
3번 목표는 성공했다! A+를 받아서 평균학점이 올라서 좋다! ㅎㅎ</p>
<h1 id="4번-목표">4번 목표</h1>
<p><img src="https://images.velog.io/images/tree_jhk/post/d78e20d8-dadb-4311-94aa-cd3824c5b3cb/image.png" alt="">
4번 목표는 초과 달성했다! 겨울방학 목표를 세웠을 때 35문제를 풀었던 상태였고 브론즈 문제들 풀면서 지냈었다. 그리고 오늘까지 포함해서 방학동안 총 84문제를 풀었다. 그래도 그때보다 코딩 실력이 나아진 것 같다.
그러나... 아직도 많이 어렵고 멀었다... 물실버1다... PS에 대해서 공부를 할수록 자료구조와 알고리즘 지식들을 정확하고 많이 알아둬야겠다는 생각이 들었다.
(그래서 자료구조와 알고리즘 수업 수강신청을 했다!)</p>
<p>이번 방학 동안 알고리즘과 자료구조 개념 자체에 대한 심화 공부는 안했고 문제풀이 위주로 했었는데 이번 3-1학기 때는 개념 심화 공부와 함께 문제풀이 양을 줄여서 내실을 튼튼히 해야할 것 같다.</p>
<h1 id="5번-목표">5번 목표</h1>
<p>5번 목표는 안했다. 나중에 정말 실력이 쌓여서 정확한 지식으로 잘 설명할 수 있을 때 중요한 것들을 써보면 좋을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모든 모양의 IoU 계산하는 방법(IoU 구현하기) - 완성판 -with cv2]]></title>
            <link>https://velog.io/@tree_jhk/%EB%AA%A8%EB%93%A0-%EB%AA%A8%EC%96%91%EC%9D%98-IoU-%EA%B3%84%EC%82%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@tree_jhk/%EB%AA%A8%EB%93%A0-%EB%AA%A8%EC%96%91%EC%9D%98-IoU-%EA%B3%84%EC%82%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Thu, 10 Feb 2022 14:09:33 GMT</pubDate>
            <description><![CDATA[<h2 id="완성판-코드">완성판 코드</h2>
<p>(수정)
코드 추가: 모델 불러오고, mIoU 판단에 쓸 이미지들 파일 경로 불러왔습니다.</p>
<p>오랜만에 글 통계 확인하니까 방문자가 많아서 지난 3월에 완성했던 임의의 모양의 mIoU 구하기 코드를 추가했습니다. - 주석은 거의 없지만, 아래에 코드에 대한 자세한 설명들을 보시면 이해되실 것 같습니다.
&#39;IoU란?&#39; 항목부터는 mIoU 설명과 코드의 기초적인 구현 아이디어를 작성했습니다.</p>
<pre><code class="language-python">&quot;&quot;&quot;
get_miou_with_cv2.py
made by tree.jhk@gmail.com
https://github.com/tree-jhk
https://velog.io/@tree_jhk/%EB%AA%A8%EB%93%A0-%EB%AA%A8%EC%96%91%EC%9D%98-IoU-%EA%B3%84%EC%82%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95
&quot;&quot;&quot;

import cv2
# import numpy
import os
import torch

global standard_threshold
global flag
flag = True
standard_threshold = 135

model=(torch.load(&quot;../CrackForest/weights_79680장_20_32_deep.pt&quot;, map_location=&#39;cpu&#39;))
flag = torch.cuda.is_available()
if (flag==True):
    model=(torch.load(&quot;../CrackForest/weights_79680장_20_32_deep.pt&quot;))
    model.cuda()
else:
    model=(torch.load(&quot;../CrackForest/weights_79680장_20_32_deep.pt&quot;, map_location=&#39;cpu&#39;))

def case_threshold(path,threshold_value):
    img=cv2.imread(path)
    img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    if(threshold_value&gt;standard_threshold):
        res,img_gray_thr = cv2.threshold(img_gray,threshold_value,255,cv2.THRESH_BINARY)
    else:
        res,img_gray_thr = cv2.threshold(img_gray,threshold_value,255,cv2.THRESH_BINARY_INV)
    return img_gray_thr

def iou(intersection,union):
    if(union!=0):
        return intersection/union
    else:
        return 0

def get_mean_miou(raw_images_path,groundtruth_images_path):

    sum_miou=0

    raw_images_list=(os.listdir(raw_images_path))
    raw_images_list.sort()
    raw_images_count=len(raw_images_list)

    for image_name in raw_images_list:
        if os.path.isfile(raw_images_path+&quot;/&quot;+image_name):
            raw_image = cv2.imread(raw_images_path+&quot;/&quot;+image_name, cv2.IMREAD_COLOR)

            raw_image = cv2.resize((cv2.imread(raw_images_path+&quot;/&quot;+image_name, cv2.IMREAD_COLOR))
                                   ,(224,224)).transpose(2,0,1).reshape(1,3,224,224)
            if(torch.cuda.is_available()):
                semantic_image = model(torch.from_numpy(raw_image).type(torch.cuda.FloatTensor)/255)
                semantic_image = semantic_image[&#39;out&#39;].cpu().detach().numpy()
                # np.transpose(image,(2,0,1)) for HWC-&gt;CHW transformation
                transpose_semantic_image = semantic_image[0].transpose(1,2,0)
                transpose_semantic_image = cv2.resize(transpose_semantic_image,(224,224))
            else:
                semantic_image = model(torch.from_numpy(raw_image).type(torch.FloatTensor)/255)
                semantic_image = semantic_image[&#39;out&#39;].detach().numpy()
                transpose_semantic_image = semantic_image[0].transpose(1,2,0)
                transpose_semantic_image = cv2.resize(transpose_semantic_image,(224,224))

            transpose_semantic_image_name=&#39;../CrackForest/save&#39;+&#39;/&#39;+image_name+&#39;.png&#39;

            ground_truth_image_name=&#39;../CrackForest/save&#39;+&#39;/&#39;+&#39;g_t&#39;+image_name+&#39;.png&#39;

            cv2.imwrite(transpose_semantic_image_name,transpose_semantic_image*255)
            # transpose_semantic_image
            ground_truth_image=cv2.resize(cv2.imread(groundtruth_images_path+&#39;/&#39;+image_name,cv2.IMREAD_COLOR),(224,224))
            cv2.imwrite(ground_truth_image_name,ground_truth_image)

            # 차선변경영역
            # 160 이상인 영역은 흰색 나머지 검정색
            class1_semantic=case_threshold(transpose_semantic_image_name,160)
            cv2.imshow(image_name,class1_semantic)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
            class1_groundtruth=case_threshold(ground_truth_image_name,160)
            cv2.imshow(image_name,class1_groundtruth)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
            # 배경영역
            # 10 이하인 영역은 흰색 나머지 검정색
            class2_semantic=case_threshold(transpose_semantic_image_name,10)
            class2_groundtruth=case_threshold(ground_truth_image_name,10)

            # 주행가능영역
            # 10 이상 160 이하인 영역은 흰색 나머지 검정색
            class3_semantic=cv2.bitwise_not(cv2.bitwise_or(class1_semantic,class2_semantic))
            class3_groundtruth=cv2.bitwise_not(cv2.bitwise_or(class1_groundtruth,class2_groundtruth))

            # 차선변경영역 iou
            class_iou =[]

            class1_intersection = cv2.countNonZero(cv2.bitwise_and(class1_semantic, class1_groundtruth))
            class1_union=cv2.countNonZero(cv2.bitwise_or(class1_semantic, class1_groundtruth))
            class_iou.append(iou(class1_intersection,class1_union))

            # 배경영역 iou
            class2_intersection = cv2.countNonZero(cv2.bitwise_and(class2_semantic, class2_groundtruth))
            class2_union=cv2.countNonZero(cv2.bitwise_or(class2_semantic, class2_groundtruth))
            class_iou.append(iou(class2_intersection,class2_union))

            # 주행가능영역 iou
            class3_intersection = cv2.countNonZero(cv2.bitwise_and(class3_semantic, class3_groundtruth))
            class3_union=cv2.countNonZero(cv2.bitwise_or(class3_semantic, class3_groundtruth))
            class_iou.append(iou(class3_intersection,class3_union))

            ch = 0
            sum = 0
            for i in range(len(class_iou)):
                if(class_iou != 0):
                    ch+=1
                    sum+=class_iou[i]
            if(ch!=0):
                miou = sum/ch
                sum_miou+=miou
                print(miou,image_name,k)
            else:
                print(&quot;No miou&quot;)

        else:
            print(&quot;file does not exists&quot;)
            return 0
    return sum_miou/raw_images_count

raw_images_path = &quot;../CrackForest/changed_Images_320장&quot;
groundtruth_images_path = &quot;../CrackForest/changed_Masks_320장&quot;

if os.path.isdir(raw_images_path):
    print(get_mean_miou(raw_images_path,groundtruth_images_path))
else:
    print(&quot;directory does not exists&quot;)</code></pre>
<h2 id="iou란">IoU란?</h2>
<p>IoU(Intersection over Union)는 Detection이나 Semantic Segmentation의 결과를 평가하기 위한 지표 중의 하나입니다.</p>
<p>Detection은 생성된 Bounding Box의 이미지와 Ground Truth 이미지를 활용해서 IoU를 구합니다.
Semantic Segmentation은 마스크 처리된 이미지와 Ground Truth 이미지를 활용해서 IoU를 구합니다.</p>
<p><img src="https://images.velog.io/images/tree_jhk/post/853f91c6-2279-4337-a7b3-ce87ea70af66/image.png" alt="">
빨간색 박스: Ground Truth
파란색 박스: Bounding Box 결과
<img src="https://images.velog.io/images/tree_jhk/post/d4fd9de1-d7ed-4180-b633-e1166b0922ee/image.png" alt="">
위와 같이, 교집합 면적을 합집합 면적으로 나눈 값을 IoU라고 합니다.
더 자세한 것은 링크 참조: <a href="https://inspace4u.github.io/dllab/lecture/2017/09/28/IoU.html">IoU에 대한 자세한 설명 포스트</a></p>
<p>저는 이번 포스트에서 <strong>임의의 모양을 갖는 시멘틱 세그멘테이션한 이미지들의  IoU값</strong>을 구해보겠습니다.</p>
<h2 id="iou-코드-및-활용-방법">IoU 코드 및 활용 방법</h2>
<p>이번 포스팅의 실습은 <strong>Road Semantic Segmantation한 결과의 IoU값</strong>을 계산한 것인데,
클래스 개별적으로 IoU를 하려면, 아래 코드를 활용해서 해당하는 클래스의 RGB값만 1(흰색)로 변환하고 나머지는 모두 0(검정색)으로 처리하면 구해집니다. Instance Segmantation도 마찬가지로 하시면 됩니다.</p>
<p><strong>아래 [구현 아이디어] 파트를 보시면 쉽게 활용 및 응용하실 것 같습니다.</strong></p>
<p>(코드는 짧은데 주석이 많아서 길어보입니다 ㅠ)</p>
<p>아래 코드가 코랩으로 실습한 코드라서 cv2.imshow()가 아닌 plt.show()를 사용했습니다.</p>
<pre><code>import cv2
import numpy as np
import matplotlib.pyplot as plt

grd_truth = cv2.imread(&#39;../Ground_truth 이미지 이름.jpg&#39;)
# Ground truth 이미지를 불러옵니다.

grd_truth_gray = cv2.cvtColor(grd_truth, cv2.COLOR_BGR2GRAY)
# 흑백으로 전환합니다. (왜냐면, cv2.threshold()를 사용해야하기 때문입니다. cv2.threshold()를 사용하는 이유는, bit_wise연산을 하려면 0,1로만 이루어진 이미지를 구해야하기 때문입니다.)

res, grd_truth_thr = cv2.threshold(grd_truth_gray, 30, 255, cv2.THRESH_BINARY)
# grd_truth_thr은 0,1로만 이루어진 numpy.ndarray입니다. 0은 해당 픽셀이 검정색 픽셀이라는 뜻이고, 1은 해당 픽셀이 흰색 픽셀이라는 뜻입니다.

masked = cv2.imread(&#39;../masked 이미지 이름.jpg&#39;)
masked_gray = cv2.cvtColor(masked, cv2.COLOR_BGR2GRAY)
res, masked_thr = cv2.threshold(masked_gray, 30, 255, cv2.THRESH_BINARY)
#마스크 처리된(segment한 이미지)도 마찬가지로 흑백으로 전환시켜줍니다.

intersection = cv2.countNonZero(cv2.bitwise_and(grd_truth_thr, masked_thr))
# and연산을 해서, 교집합(같은 영역을 비교해서 해당 픽셀에서 둘 다 1이면 교집합이기 때문에 1로 연산합니다.)을 구합니다.
# 그리고 countNonZero로 픽셀이 0이 아닌 것만(검정 픽셀) 계산합니다. 그것이 면적입니다.
plt.imshow(cv2.bitwise_and(grd_truth_thr, masked_thr), cmap=&#39;gray&#39;)
plt.show()

union = cv2.countNonZero(cv2.bitwise_or(grd_truth_thr,masked_thr))
# or연산을 해서, 합집합(같은 영역을 비교해서 해당 픽셀에서 어느 하나라도 1이면 1로 처리해서 합집합을 구현합니다.)을 구합니다.
# 그리고 countNonZero로 픽셀이 0이 아닌 것만(검정 픽셀) 계산합니다. 그것이 면적입니다.
plt.imshow(cv2.bitwise_or(grd_truth_thr, masked_thr), cmap=&#39;gray&#39;)
plt.show()

IoU = intersection / union

print(intersection, union, IoU)</code></pre><h2 id="실습-결과">실습 결과</h2>
<p>Ground Truth 이미지: <img src="https://images.velog.io/images/tree_jhk/post/a4fa7364-40bf-488f-a1d8-7042d8b1f642/0001.jpg" alt="">
Masked 이미지: <img src="https://images.velog.io/images/tree_jhk/post/5b6878c1-2fbd-4c2c-8236-0fd2ffa2418a/0018.jpg" alt="">
교집합 이미지:<img src="https://images.velog.io/images/tree_jhk/post/7a63ffdc-aa12-4d6a-9f11-3d24b6cec746/image.png" alt="">
합집합 이미지:<img src="https://images.velog.io/images/tree_jhk/post/4122316f-e48d-4315-85a9-12b20150a901/image.png" alt="">
IoU 결과값: 0.26 (교집합 / 합집합)</p>
<h2 id="구현-아이디어">구현 아이디어</h2>
<p>우선, 전체 이미지에서 <strong>세그멘테이션된 이미지를 grayscale로</strong> 바꿉니다.</p>
<p>grayscale이미지에서 <strong>검정색이 아닌 나머지 모든 픽셀은 세그멘테이션이 된 이미지</strong>이기 때문에 threshold값을 조절해서 <strong>나머지 픽셀들을 1(흰색)으로 변경</strong>시킵니다.</p>
<p>그렇게 되면, <strong>ndarry가 모두 0 or 1로 구성</strong>됐기 때문에 <strong>bitwise연산을 이용</strong>할 수 있습니다. 자세한 것은 코드에 주석으로 달았습니다.</p>
<p>따라서 <strong>합집합 부분은 or연산</strong>을 활용했고, <strong>교집합 부분은 and연산</strong>을 활용했습니다.
bitwise에 관한 글: <a href="https://copycoding.tistory.com/156">bitwise 글</a></p>
<p>그리고 <strong>CountNonZero()함수를 이용</strong>해서 <strong>전체 ndarry 값 중에서 0이 아닌 값의 개수를 모두 셉니다</strong>. <strong>이 개수가 전체 픽셀 중에서 흰색 영역의 픽셀 수</strong>입니다.
결과적으로, <strong>흰색 영역의 면적</strong>을 구한 것입니다.
최종적으로, <strong>IoU는 이러한 방식으로 구현</strong>할 수 있었습니다.</p>
<p>포스팅하면서 깨달은 것은, 내가 만든 코드가 아직 각 클래스별로 IoU값을 구하는 것이 아니라 전체를 그냥 계산한 것 같다. 클래스별로 구하는 것에 대한 것은 포스트를 읽는 분께서 조금만 코드를 더 추가하면 가능해보인다.</p>
<h2 id="임의의-모양의-iou를-계산하려고-한-이유">임의의 모양의 IoU를 계산하려고 한 이유</h2>
<p>IoU를 계산하려고 했는데, 관련된 오픈 코드들의 매개변수가 잘 파악이 안되고 적용하는 방법을 명확히 몰라서 적용이 어려워서 직접 구현해봤다.
결과적으로 잘 수행되는 것 같다.</p>
<h2 id="시행착오">시행착오</h2>
<p>사실 원래는 Coutours라는 opencv 개념을 활용해서 세그멘테이션된 면적의 경계를 따고, 그 경계의 면적을 구하려고 했는데, 이렇게 하면 잘 안되기도 하고 계산도 많고 과정도 훨씬 길다.</p>
<p>고민하다가 CountNonZero()를 활용하면 될 것 같았고 결국 문제를 해결할 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ios_base::sync_with_stdio(false); 구문을 쓸 때의 주의 사항]]></title>
            <link>https://velog.io/@tree_jhk/iosbasesyncwithstdiofalse-%EA%B5%AC%EB%AC%B8%EC%9D%84-%EC%93%B8-%EB%95%8C%EC%9D%98-%EC%A3%BC%EC%9D%98-%EC%82%AC%ED%95%AD</link>
            <guid>https://velog.io/@tree_jhk/iosbasesyncwithstdiofalse-%EA%B5%AC%EB%AC%B8%EC%9D%84-%EC%93%B8-%EB%95%8C%EC%9D%98-%EC%A3%BC%EC%9D%98-%EC%82%AC%ED%95%AD</guid>
            <pubDate>Mon, 31 Jan 2022 10:07:31 GMT</pubDate>
            <description><![CDATA[<h2 id="ios_basesync_with_stdiofalse-구문을-쓰는-이유">ios_base::sync_with_stdio(false); 구문을 쓰는 이유</h2>
<p>결론적으로 이야기하면, c++ 사용자가 <strong>더 빠른 속도로 입출력을 하기 위해</strong>서 사용하는 구문이라고 보면 됩니다.</p>
<p>우선,
<strong>ios_base::sync_with_stdio(true); 구문은</strong>
c++의 iostream 파일과 c의 stdio 파일을 동기화시켜줘서, 두 구문을 모두 사용할 수 있게 해준다. 하지만, 이렇게 될 경우, <strong>c++의 버퍼와 c의 버퍼 둘 다 사용</strong>하기 때문에 <strong>딜레이가 발생</strong>한다고 합니다.</p>
<p>따라서,
<strong>이 딜레이를 줄이기 위해
ios_base::sync_with_stdio(false); 구문을 써서</strong>
두 파일의 동기화를 끊고, c++의 버퍼만을 사용하게 된다. 이렇게 해서 앞서 말했던 딜레이가 사라지게 되서 조금이라도 더 빠르게 입출력을 할 수 있게 됩니다.</p>
<h2 id="ios_basesync_with_stdiofalse-주의-사항">ios_base::sync_with_stdio(false); 주의 사항</h2>
<p>더 빠른 입출력을 위해 해당 구문을 사용한다면, printf, scanf, puts 등 <strong>C언어 버퍼의 구문을 사용하게 되면 출력 형식이 잘못될 수가 있습니다.</strong></p>
<p>저의 경우, 해당 구문이 가지는 이유는 모르고, 그냥 사용하면 빠르다는 것만 알고 <strong>c언어 버퍼의 구문인 puts()를 사용했는데,</strong> visiual studio 2022에서는 잘만 출력이 되는 것이 <strong>백준에 코드를 올리면 계속 틀리다고 나와서 매우 난감했습니다.</strong></p>
<h3 id="사건의-발단일기">사건의 발단(일기)</h3>
<p><a href="https://www.acmicpc.net/problem/6603">[백준] 6603번 로또</a> 문제를 풀려고 보니까, [출력 형식이 잘못되었습니다] 결과가 계속 나왔다... 도저히 어떤 것이 틀렸는지 감이 안 왔다.
<img src="https://images.velog.io/images/tree_jhk/post/1c447bd9-0c32-40f9-bb12-bd3a815121b8/image.png" alt="">
실제로 출력 결과도 다른 블로그에서와 똑같이 나왔다.
<img src="https://images.velog.io/images/tree_jhk/post/26c3960f-916e-4905-a0ef-c96601aa1fa9/image.png" alt="">
문제의 원인은, 
구문 중간에 cout&lt;&lt;&quot;\n&quot;; 대신에 c언어 버퍼를 사용하는 puts()를 사용해서 출력 형식이 계속 잘못됐다고 나왔다.
<img src="https://images.velog.io/images/tree_jhk/post/61f985c5-6163-46c1-ba53-14555f016b18/image.png" alt="">
참고 사이트: <a href="https://ideone.com/">ideone</a></p>
<p>그래서 수정을 하니까 정상적으로 정답 처리 됐다.</p>
<h3 id="문제의-코드">문제의 코드</h3>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;iostream&gt;
#include &lt;stdio.h&gt;
#include &lt;string&gt;
#include &lt;string.h&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;math.h&gt;
using namespace std;
int ch[15], a[10], lotto[15], k = 1;
void DFS(int loc, int L) {
    if (L == 7) {
        for (int i = 1; i &lt;= 6; i++)
            cout &lt;&lt; a[i] &lt;&lt; &quot; &quot;;
        puts(&quot;&quot;);
        return;
    }
    else {
        for(int i=loc;i&lt;=k;i++)
            if (ch[i] == 0) {
                ch[i] = 1;
                a[L] = lotto[i];
                DFS(i, L + 1);
                ch[i] = 0;
            }
    }
}

int main(int argc, const char* argv[]) {
    ios_base::sync_with_stdio(false);
    cout.tie(NULL);
    cin.tie(NULL);
    while (1) {
        cin &gt;&gt; k;
        if (k == 0)
            return 0;
        for (int i = 1; i &lt;= k; i++)
            cin &gt;&gt; lotto[i];
        DFS(1, 1);
        puts(&quot;&quot;);
        fill_n(ch, 15, 0);
    }
    return 0;
}</code></pre><h3 id="정답-코드">정답 코드</h3>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;iostream&gt;
#include &lt;stdio.h&gt;
#include &lt;string&gt;
#include &lt;string.h&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;math.h&gt;
using namespace std;
int ch[15], a[10], lotto[15], k = 1;
void DFS(int loc, int L) {
    if (L == 7) {
        for (int i = 1; i &lt;= 6; i++)
            cout &lt;&lt; a[i] &lt;&lt; &quot; &quot;;
        cout &lt;&lt; &quot;\n&quot;;
        return;
    }
    else {
        for(int i=loc;i&lt;=k;i++)
            if (ch[i] == 0) {
                ch[i] = 1;
                a[L] = lotto[i];
                DFS(i, L + 1);
                ch[i] = 0;
            }
    }
}

int main(int argc, const char* argv[]) {
    ios_base::sync_with_stdio(false);
    cout.tie(NULL);
    cin.tie(NULL);
    while (1) {
        cin &gt;&gt; k;
        if (k == 0)
            return 0;
        for (int i = 1; i &lt;= k; i++)
            cin &gt;&gt; lotto[i];
        DFS(1, 1);
        cout&lt;&lt;&quot;\n&quot;;
        fill_n(ch, 15, 0);
    }
    return 0;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 2309번 : 일곱 난쟁이 - [C++]]]></title>
            <link>https://velog.io/@tree_jhk/%EB%B0%B1%EC%A4%80-2309%EB%B2%88-%EC%9D%BC%EA%B3%B1-%EB%82%9C%EC%9F%81%EC%9D%B4-C</link>
            <guid>https://velog.io/@tree_jhk/%EB%B0%B1%EC%A4%80-2309%EB%B2%88-%EC%9D%BC%EA%B3%B1-%EB%82%9C%EC%9F%81%EC%9D%B4-C</guid>
            <pubDate>Sun, 30 Jan 2022 16:53:50 GMT</pubDate>
            <description><![CDATA[<p>링크: <a href="https://www.acmicpc.net/problem/2309">[백준] 2309번 : 일곱 난쟁이</a></p>
<h3 id="문제">문제</h3>
<p><img src="https://images.velog.io/images/tree_jhk/post/2e64cbc7-2a42-4949-b20a-473a3d30453d/image.png" alt="">
<img src="https://images.velog.io/images/tree_jhk/post/f87ea75f-6989-4c4e-8e76-6316cb1be603/image.png" alt=""></p>
<h3 id="설명">설명</h3>
<p>어제 오늘부터, <a href="https://www.acmicpc.net/workbook/view/2052">N과 M 시리즈</a>를 풀면서, 재귀 함수를 이용한 백트래킹 알고리즘을 열심히 연습했고, 해당 문제가 완전 탐색 유형이기 때문에 백트래킹 알고리즘을 활용해서 문제를 풀어봤습니다.
다른 분들 풀이를 보니까, 다른 분들은 for문을 3번 써서 재귀 함수를 쓰지 않고 문제를 해결했습니다.</p>
<p>제 생각에는 재귀 함수를 쓰면 좀 더 일반적인 상황에서의 풀이가 될 것 같아서 공유하게 됐습니다.</p>
<p>저의 재귀 함수 풀이와 저의 for문 풀이를 함께 올리도록 하겠습니다.</p>
<p>평소에 그냥 문제 풀고 포스팅은 따로 안 했는데, 이번 문제는 풀이도 다양하고, exit()를 처음 접해서 올리게 됐습니다.</p>
<p>특이한 부분에 대한 주석도 포함했습니다!</p>
<h3 id="풀이">풀이</h3>
<h6 id="재귀함수를-이용한-풀이-주석을-자세히-썼습니다">재귀함수를 이용한 풀이 (주석을 자세히 썼습니다...)</h6>
<p>아래 사진이 코드의 DFS 트리를 그려본 것입니다!
<img src="https://images.velog.io/images/tree_jhk/post/1600c68d-ee04-4ee6-b55d-98187afa27f9/%EC%9D%BC%EA%B3%B1%20%EB%82%9C%EC%9F%81%EC%9D%B4%20%EC%84%A4%EB%AA%85.jpg" alt=""></p>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;iostream&gt;
#include &lt;algorithm&gt; #sort알고리즘을 사용하기 위함.
using namespace std;
int cnt = 0, sum = 0, arr[10], ch[10];

void DFS(int L) { #L은 DFS 트리의 레벨(혹은 깊이)를 의미합니다.
    if (cnt == 7) {
        if (sum == 100) {
        #cnt(count의 약자)가 7일 때, 합이 100인 경우가 출력을 해야하는 경우입니다.
            for (int i = 1;i &lt;= 9;i++)
                if (ch[i] == 1)
                    cout &lt;&lt; arr[i] &lt;&lt; &quot;\n&quot;;
            exit(0); #주의할 부분입니다.
//문제에서 &#39;가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.&#39;라고 했고, 
//&#39;일곱 난쟁이를 찾을 수 없는 경우는 없다.&#39;라고 했기 때문에
//합이 100인 경우가 무조건 존재하고,
//여러 경우 중에 처음 등장하는 경우 한번만 출력하면 되기 때문에
//#exit(0)를 이용해서 재귀함수를 완전히 빠져나와야합니다.
//달리 이야기하면, return으로 빠져나오는 것이 아니라,
//stack에 남아있는 모든 함수를 종료해야 합니다.
//그래서 제 풀이의 경우, exit(0)를 이용해서 빠져나와야 문제가 해결됩니다.
        }
        return;
    }
    if (L == 10)
    //DFS의 깊이가(L) 9를 넘어서는 경우, return해서 마무리해야 DFS가 무한히 반복되지 않습니다.
        return;
    else {
        sum += arr[L];
        ch[L] = 1;
        cnt++;
        DFS(L + 1);

        //ch[L](check의 약자로, 값을 받아서 더했는지 안 더했는지를 0, 1로 구분합니다.
        //sum에 계속 더해주고
        //sum에 더해줄 때마다 cnt++을 해서 확인한 &#39;난쟁이 키&#39;가 몇 개인지 저장합니다.

        sum -= arr[L];
        ch[L] = 0;
        cnt--;
        DFS(L + 1);
        //키를 더하지 않을 때의 경우입니다.
    }
}

int main(int argc, const char* argv[]) {
    ios_base::sync_with_stdio(false);
    cout.tie(NULL);
    cin.tie(NULL);
    for (int i = 1;i &lt;= 9;i++)
        cin &gt;&gt; arr[i];
    sort(arr + 1, arr + 10);
    DFS(1);
    return 0;
}</code></pre><h6 id="for문을-3번-쓴-풀이">for문을 3번 쓴 풀이</h6>
<pre><code>#define _CRT_SECURE_NO_WARNINGS
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
using namespace std;

int main(int argc, const char* argv[]) {
    ios_base::sync_with_stdio(false);
    cout.tie(NULL);
    cin.tie(NULL);
    int a[10], sum = 0, i, j, k;

    for (i = 1; i &lt;= 9; i++) {
        cin &gt;&gt; a[i];
        sum += a[i];
    }
    sort(a + 1, a + 10);
    for (i = 1; i &lt;= 9; i++) {
        for (j = i+1; j &lt;= 9; j++) {
            if (sum - a[i] - a[j] == 100) {
                for (k = 1; k &lt;= 9; k++) {
                    if (k != i &amp;&amp; k != j) {
                        cout &lt;&lt; a[k] &lt;&lt; &quot;\n&quot;;
                    }
                }
                return 0;
                //단 한번의 경우만 출력하면 되기 때문에, 최초로 등장한 경우만 출력하면 됩니다.
            }
        }
    }
    return 0;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[ROS camera calibration 카메라 캘리브레이션 하기]]></title>
            <link>https://velog.io/@tree_jhk/ROS-camera-calibration-%EC%B9%B4%EB%A9%94%EB%9D%BC-%EC%BA%98%EB%A6%AC%EB%B8%8C%EB%A0%88%EC%9D%B4%EC%85%98-%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tree_jhk/ROS-camera-calibration-%EC%B9%B4%EB%A9%94%EB%9D%BC-%EC%BA%98%EB%A6%AC%EB%B8%8C%EB%A0%88%EC%9D%B4%EC%85%98-%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 30 Jan 2022 16:40:41 GMT</pubDate>
            <description><![CDATA[<h1 id="참고-자료">참고 자료</h1>
<p>PinkWink님의 [ROS 카메라 캘리브레이션 수행하기 포스트] (<a href="https://pinkwink.kr/1353">https://pinkwink.kr/1353</a>)
ROS Wiki에서의 <a href="http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration">How to Calibrate a Monocular Camera</a></p>
<h1 id="방법">방법</h1>
<p>PinkWink님의 자료만 참고해도 충분합니다.
다만, 카메라를 사용하는 방법은 해당 포스트에는 없기 때문에, 다음의 포스팅을 사용하시면 됩니다.
<a href="https://msc9533.github.io/2020/02/ros-multi-usb-cam/">ROS usb cam 2개이상의 카메라에서 사용하기</a></p>
<h1 id="결과">결과</h1>
<p><img src="https://images.velog.io/images/tree_jhk/post/c82c776b-4f65-4075-9a6e-33e5ce987f27/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7,%202022-01-01%2002-26-33.png" alt=""></p>
<pre><code>[image]

width #이미지 너비(픽셀 수)
640

height #이미지 높이(픽셀 수)
480

[narrow_stereo] #monocular camera로 캘리브레이션을 했는데, 카메라 이름에 streo가 포함되서 이유를 알고 싶어진다.

camera matrix #카메라의 이미지에 대한 정보이다. 3x3 행렬로 이루어졌다.
#이 행렬이 앞으로, 2차원 이미지를 3차원으로 변환할 때 필요한 행렬이다.
646.704789 0.000000 309.524761
0.000000 646.809457 225.359166
0.000000 0.000000 1.000000

distortion #왜곡 계수
0.004350 -0.049532 0.002752 -0.000092 0.000000

rectification #정류 행렬(rectification)
1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000

projection #투영 행렬
645.670288 0.000000 309.368818 0.000000
0.000000 646.799561 226.056659 0.000000
0.000000 0.000000 1.000000 0.000000
</code></pre><h1 id="동기">동기</h1>
<p>학부연구생 진행 중에, 카메라로 받은 정보와 라이다로 받은 정보를 센서 퓨징을 해야 하는 것을 알게 됐다.
그에 앞서, 우선은 로봇이 카메라로 받은 이미지의 2차원 정보를 통해서 3차원 좌표로 변환하는 Camera calibration을 해야한다는 것을 알게 됐다.</p>
<p>연구실에서 더 제대로 하겠지만, 우선은 노트북 카메라로 수행했다.
그리고 프린팅된 체커보드는 사용하지 않고, 태블릿 PC에 체커보드를 이미지로 띄워서, 수행했다.
우선 실습만 하고 싶어서 급한대로 집에서 태블릿 PC를 이용하게 됐다.</p>
]]></description>
        </item>
    </channel>
</rss>