반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

https://d2l.ai/chapter_preface/index.html

 

Preface — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

Preface

 

Just a few years ago, there were no legions of deep learning scientists developing intelligent products and services at major companies and startups. When we entered the field, machine learning did not command headlines in daily newspapers. Our parents had no idea what machine learning was, let alone why we might prefer it to a career in medicine or law. Machine learning was a blue skies academic discipline whose industrial significance was limited to a narrow set of real-world applications, including speech recognition and computer vision. Moreover, many of these applications required so much domain knowledge that they were often regarded as entirely separate areas for which machine learning was one small component. At that time, neural networks—the predecessors of the deep learning methods that we focus on in this book—were generally regarded as outmoded.

 

불과 몇 년 전만 해도 대기업과 스타트업에는 지능형 제품과 서비스를 개발하는 딥러닝 과학자 군단이 없었습니다. 우리가 현장에 들어갔을 때 머신러닝은 일간 신문의 헤드라인을 장식하지 않았습니다. 우리 부모님은 기계 학습이 무엇인지 전혀 몰랐고, 우리가 의학이나 법률 분야의 직업보다 기계 학습을 선호하는 이유도 몰랐습니다. 기계 학습은 산업적 중요성이 음성 인식 및 컴퓨터 비전을 포함한 좁은 실제 응용 프로그램 집합으로 제한되는 파란 하늘 학문 분야였습니다. 더욱이 이러한 응용 프로그램 중 다수에는 너무 많은 도메인 지식이 필요했기 때문에 기계 학습이 하나의 작은 구성 요소인 완전히 별도의 영역으로 간주되는 경우가 많았습니다. 그 당시에는 이 책에서 중점적으로 다루는 딥러닝 방법의 전신인 신경망이 일반적으로 시대에 뒤떨어진 것으로 간주되었습니다.

 

Yet in just few years, deep learning has taken the world by surprise, driving rapid progress in such diverse fields as computer vision, natural language processing, automatic speech recognition, reinforcement learning, and biomedical informatics. Moreover, the success of deep learning in so many tasks of practical interest has even catalyzed developments in theoretical machine learning and statistics. With these advances in hand, we can now build cars that drive themselves with more autonomy than ever before (though less autonomy than some companies might have you believe), dialogue systems that debug code by asking clarifying questions, and software agents beating the best human players in the world at board games such as Go, a feat once thought to be decades away. Already, these tools exert ever-wider influence on industry and society, changing the way movies are made, diseases are diagnosed, and playing a growing role in basic sciences—from astrophysics, to climate modeling, to weather prediction, to biomedicine.

 

그러나 불과 몇 년 만에 딥 러닝은 컴퓨터 비전, 자연어 처리, 자동 음성 인식, 강화 학습, 생물의학 정보학과 같은 다양한 분야에서 급속한 발전을 이루며 세상을 놀라게 했습니다. 더욱이, 실용적인 관심을 끄는 수많은 작업에서 딥 러닝의 성공은 이론적 기계 학습과 통계의 발전을 촉진하기도 했습니다. 이러한 발전을 통해 우리는 이제 그 어느 때보다 더 많은 자율성을 갖고 스스로 운전하는 자동차(일부 회사에 비해 자율성은 떨어지지만), 명확한 질문을 통해 코드를 디버깅하는 대화 시스템, 최고의 인간을 이기는 소프트웨어 에이전트를 만들 수 있습니다. 한때 수십 년이 걸릴 것으로 생각되었던 업적인 바둑과 같은 보드 게임에서 전 세계 플레이어가 게임을 즐기고 있습니다. 이미 이러한 도구는 영화 제작 방식, 질병 진단 방식을 변화시키고 천체 물리학에서 기후 모델링, 날씨 예측, 생물 의학에 이르기까지 기초 과학에서 점점 더 많은 역할을 수행하면서 산업과 사회에 더욱 광범위한 영향을 미치고 있습니다.

 

About This Book

 

This book represents our attempt to make deep learning approachable, teaching you the concepts, the context, and the code.

 

이 책은 딥 러닝을 접근하기 쉽게 만들고 개념, 맥락, 코드를 가르치려는 우리의 시도를 보여줍니다.

 

One Medium Combining Code, Math, and HTML

For any computing technology to reach its full impact, it must be well understood, well documented, and supported by mature, well-maintained tools. The key ideas should be clearly distilled, minimizing the onboarding time needed to bring new practitioners up to date. Mature libraries should automate common tasks, and exemplar code should make it easy for practitioners to modify, apply, and extend common applications to suit their needs.

 

모든 컴퓨팅 기술이 완전한 영향력을 발휘하려면 이를 잘 이해하고 문서화해야 하며 성숙하고 잘 관리되는 도구의 지원을 받아야 합니다. 핵심 아이디어는 명확하게 정리되어 새로운 실무자에게 최신 정보를 제공하는 데 필요한 온보딩 시간을 최소화해야 합니다. 성숙한 라이브러리는 일반적인 작업을 자동화해야 하며, 예시 코드를 통해 실무자는 필요에 따라 일반 애플리케이션을 쉽게 수정, 적용 및 확장할 수 있어야 합니다.

 

As an example, take dynamic web applications. Despite a large number of companies, such as Amazon, developing successful database-driven web applications in the 1990s, the potential of this technology to aid creative entrepreneurs was realized to a far greater degree only in the past ten years, owing in part to the development of powerful, well-documented frameworks.

 

예를 들어 동적 웹 애플리케이션을 살펴보겠습니다. 1990년대 아마존 등 수많은 기업이 데이터베이스 기반 웹 애플리케이션을 성공적으로 개발했음에도 불구하고,창의적 기업가를 지원하는 이 기술의 잠재력은 부분적으로 강력하고 잘 문서화된 프레임워크의 개발 덕분에 지난 10년 동안에야 훨씬 더 크게 실현되었습니다.

 

When we started this book project, there were no resources that simultaneously (i) remained up to date; (ii) covered the breadth of modern machine learning practices with sufficient technical depth; and (iii) interleaved exposition of the quality one expects of a textbook with the clean runnable code that one expects of a hands-on tutorial. We found plenty of code examples illustrating how to use a given deep learning framework (e.g., how to do basic numerical computing with matrices in TensorFlow) or for implementing particular techniques (e.g., code snippets for LeNet, AlexNet, ResNet, etc.) scattered across various blog posts and GitHub repositories. However, these examples typically focused on how to implement a given approach, but left out the discussion of why certain algorithmic decisions are made. While some interactive resources have popped up sporadically to address a particular topic, e.g., the engaging blog posts published on the website Distill, or personal blogs, they only covered selected topics in deep learning, and often lacked associated code. On the other hand, while several deep learning textbooks have emerged—e.g., Goodfellow et al. (2016), which offers a comprehensive survey on the basics of deep learning—these resources do not marry the descriptions to realizations of the concepts in code, sometimes leaving readers clueless as to how to implement them. Moreover, too many resources are hidden behind the paywalls of commercial course providers.

 

우리가 이 도서 프로젝트를 시작했을 때 동시에 (i) 최신 상태로 유지되는 리소스가 없었습니다. (ii) 충분한 기술적 깊이로 현대 기계 학습 사례의 폭을 다루었습니다. (iii) 실습 튜토리얼에서 기대하는 깔끔한 실행 가능 코드를 사용하여 교과서에서 기대하는 품질을 인터리브 방식으로 설명합니다. 우리는 주어진 딥 러닝 프레임워크를 사용하는 방법(예: TensorFlow에서 행렬을 사용하여 기본 수치 계산을 수행하는 방법) 또는 특정 기술을 구현하는 방법(예: LeNet, AlexNet, ResNet 등의 코드 조각)을 설명하는 많은 코드 예제를 발견했습니다. 다양한 블로그 게시물과 GitHub 저장소에 걸쳐 있습니다. 그러나 이러한 예는 일반적으로 주어진 접근 방식을 구현하는 방법에 중점을 두었지만 특정 알고리즘 결정이 내려지는 이유에 대한 논의는 생략했습니다. 특정 주제를 다루기 위해 일부 대화형 리소스(예: Distill 웹사이트에 게시된 매력적인 블로그 게시물 또는 개인 블로그)가 산발적으로 등장했지만 딥 러닝에서 선택된 주제만 다루었고 관련 코드가 부족한 경우가 많았습니다. 반면에 여러 딥러닝 교과서가 등장했지만(예: Goodfellow et al. (2016), 딥 러닝의 기본에 대한 포괄적인 조사를 제공합니다. 이러한 리소스는 설명과 코드의 개념 실현을 결합하지 않으며 때로는 독자가 이를 구현하는 방법에 대해 단서가 없게 만듭니다. 더욱이, 상업용 강좌 제공업체의 유료화벽 뒤에는 너무 많은 리소스가 숨겨져 있습니다.

 

We set out to create a resource that could (i) be freely available for everyone; (ii) offer sufficient technical depth to provide a starting point on the path to actually becoming an applied machine learning scientist; (iii) include runnable code, showing readers how to solve problems in practice; (iv) allow for rapid updates, both by us and also by the community at large; and (v) be complemented by a forum for interactive discussion of technical details and to answer questions.

 

우리는 (i) 모든 사람이 무료로 사용할 수 있는 리소스를 만들기 시작했습니다. (ii) 실제로 응용 기계 학습 과학자가 되기 위한 출발점을 제공하기에 충분한 기술적 깊이를 제공합니다. (iii) 실행 가능한 코드를 포함하여 독자에게 실제로 문제를 해결하는 방법을 보여줍니다. (iv) 당사와 커뮤니티 전반에 의한 신속한 업데이트를 허용합니다. (v) 기술 세부 사항에 대한 대화식 토론과 질문에 답변할 수 있는 포럼으로 보완됩니다.

 

These goals were often in conflict. Equations, theorems, and citations are best managed and laid out in LaTeX. Code is best described in Python. And webpages are native in HTML and JavaScript. Furthermore, we want the content to be accessible both as executable code, as a physical book, as a downloadable PDF, and on the Internet as a website. No workflows seemed suited to these demands, so we decided to assemble our own (Section 23.6). We settled on GitHub to share the source and to facilitate community contributions; Jupyter notebooks for mixing code, equations and text; Sphinx as a rendering engine; and Discourse as a discussion platform. While our system is not perfect, these choices strike a compromise among the competing concerns. We believe that Dive into Deep Learning might be the first book published using such an integrated workflow.

 

이러한 목표는 종종 충돌했습니다. 방정식, 정리 및 인용은 LaTeX에서 가장 잘 관리되고 배치됩니다. 코드는 Python에서 가장 잘 설명됩니다. 그리고 웹페이지는 HTML과 JavaScript로 기본 제공됩니다. 또한 우리는 콘텐츠가 실행 가능한 코드, 실제 책, 다운로드 가능한 PDF, 인터넷 웹사이트 모두에서 액세스할 수 있기를 원합니다. 이러한 요구 사항에 적합한 워크플로가 없어 보였으므로 자체적으로 구성하기로 결정했습니다(섹션 23.6). 우리는 소스를 공유하고 커뮤니티 기여를 촉진하기 위해 GitHub에 정착했습니다. 코드, 방정식 및 텍스트를 혼합하기 위한 Jupyter 노트북 렌더링 엔진으로서의 Sphinx; 토론 플랫폼으로서의 담론. 우리 시스템이 완벽하지는 않지만 이러한 선택은 경쟁하는 문제들 사이에서 타협점을 찾습니다. 우리는 Dive into Deep Learning이 이러한 통합 워크플로를 사용하여 출판된 최초의 책이 될 것이라고 믿습니다.

 

Learning by Doing

Many textbooks present concepts in succession, covering each in exhaustive detail. For example, the excellent textbook of Bishop (2006), teaches each topic so thoroughly that getting to the chapter on linear regression requires a nontrivial amount of work. While experts love this book precisely for its thoroughness, for true beginners, this property limits its usefulness as an introductory text.

 

많은 교과서에서는 각 개념을 철저하게 자세히 다루면서 개념을 연속적으로 제시합니다. 예를 들어, Bishop(2006)의 훌륭한 교과서는 각 주제를 너무 철저하게 가르치기 때문에 선형 회귀에 관한 장에 도달하려면 적지 않은 양의 작업이 필요합니다. 전문가들은 이 책의 철저함 때문에 좋아하지만, 진정한 초보자들에게는 입문용 텍스트로서의 유용성이 제한됩니다.

 

In this book, we teach most concepts just in time. In other words, you will learn concepts at the very moment that they are needed to accomplish some practical end. While we take some time at the outset to teach fundamental preliminaries, like linear algebra and probability, we want you to taste the satisfaction of training your first model before worrying about more esoteric concepts.

 

이 책에서 우리는 대부분의 개념을 적시에 가르칩니다. 즉, 실제적인 목적을 달성하기 위해 필요한 바로 그 순간에 개념을 배우게 됩니다. 선형 대수학 및 확률과 같은 기본 예비 과정을 가르치기 위해 처음에는 시간을 할애하지만, 더 난해한 개념에 대해 걱정하기 전에 첫 번째 모델 교육의 만족감을 맛보시기 바랍니다.

 

Aside from a few preliminary notebooks that provide a crash course in the basic mathematical background, each subsequent chapter both introduces a reasonable number of new concepts and provides several self-contained working examples, using real datasets. This presented an organizational challenge. Some models might logically be grouped together in a single notebook. And some ideas might be best taught by executing several models in succession. By contrast, there is a big advantage to adhering to a policy of one working example, one notebook: This makes it as easy as possible for you to start your own research projects by leveraging our code. Just copy a notebook and start modifying it.

 

기본 수학적 배경에 대한 단기 집중 강좌를 제공하는 몇 가지 예비 노트북 외에도 각 후속 장에서는 합리적인 수의 새로운 개념을 소개하고 실제 데이터 세트를 사용하여 몇 가지 독립적인 작업 예제를 제공합니다. 이는 조직적인 과제를 제시했습니다. 일부 모델은 논리적으로 단일 노트북에 함께 그룹화될 수 있습니다. 그리고 일부 아이디어는 여러 모델을 연속적으로 실행함으로써 가장 잘 배울 수 있습니다. 대조적으로, 하나의 작업 예제, 하나의 노트북 정책을 고수하면 큰 이점이 있습니다. 이를 통해 우리 코드를 활용하여 자신의 연구 프로젝트를 가능한 한 쉽게 시작할 수 있습니다. 노트북을 복사하고 수정을 시작하세요.

 

Throughout, we interleave the runnable code with background material as needed. In general, we err on the side of making tools available before explaining them fully (often filling in the background later). For instance, we might use stochastic gradient descent before explaining why it is useful or offering some intuition for why it works. This helps to give practitioners the necessary ammunition to solve problems quickly, at the expense of requiring the reader to trust us with some curatorial decisions.

 

전체적으로 우리는 필요에 따라 실행 가능한 코드를 배경 자료와 인터리브합니다. 일반적으로 우리는 도구를 완전히 설명하기 전에 도구를 사용 가능한 상태로 만드는 실수를 합니다(종종 나중에 배경을 채우는 경우가 많습니다). 예를 들어, 확률적 경사하강법이 왜 유용한지 설명하거나 작동하는 이유에 대한 직관을 제공하기 전에 확률적 경사하강법을 사용할 수 있습니다. 이는 독자가 일부 큐레이터 결정에 대해 우리를 신뢰하도록 요구하는 대신 실무자에게 문제를 신속하게 해결하는 데 필요한 수단을 제공하는 데 도움이 됩니다.

 

This book teaches deep learning concepts from scratch. Sometimes, we delve into fine details about models that would typically be hidden from users by modern deep learning frameworks. This comes up especially in the basic tutorials, where we want you to understand everything that happens in a given layer or optimizer. In these cases, we often present two versions of the example: one where we implement everything from scratch, relying only on NumPy-like functionality and automatic differentiation, and a more practical example, where we write succinct code using the high-level APIs of deep learning frameworks. After explaining how some component works, we rely on the high-level API in subsequent tutorials.

 

이 책은 딥러닝 개념을 처음부터 가르쳐줍니다. 때때로 우리는 최신 딥 러닝 프레임워크에 의해 일반적으로 사용자에게 숨겨지는 모델에 대한 세부 정보를 조사합니다. 이는 특히 특정 레이어나 옵티마이저에서 발생하는 모든 것을 이해하기를 원하는 기본 튜토리얼에서 나타납니다. 이러한 경우 우리는 종종 두 가지 버전의 예제를 제시합니다. 하나는 NumPy와 유사한 기능과 자동 차별화에만 의존하여 처음부터 모든 것을 구현하는 버전이고, 다른 하나는 고급 API를 사용하여 간결한 코드를 작성하는 보다 실용적인 예시입니다. 딥러닝 프레임워크. 일부 구성 요소의 작동 방식을 설명한 후 후속 자습서에서는 고급 API를 사용합니다.

 

Content and Structure

 

The book can be divided into roughly three parts, dealing with preliminaries, deep learning techniques, and advanced topics focused on real systems and applications (Fig. 1).

 

이 책은 대략 세 부분으로 나누어 실제 시스템과 애플리케이션에 초점을 맞춘 예비, 딥러닝 기법, 고급 주제를 다루고 있습니다(그림 1).

 

Fig. 1  Book structure.

 

  • Part 1: Basics and Preliminaries. Section 1 is an introduction to deep learning. Then, in Section 2, we quickly bring you up to speed on the prerequisites required for hands-on deep learning, such as how to store and manipulate data, and how to apply various numerical operations based on elementary concepts from linear algebra, calculus, and probability. Section 3 and Section 5 cover the most fundamental concepts and techniques in deep learning, including regression and classification; linear models; multilayer perceptrons; and overfitting and regularization.

1부: 기초 및 예비. 섹션 1은 딥러닝에 대한 소개입니다. 그런 다음 2장에서는 데이터를 저장하고 조작하는 방법, 선형대수학, 미적분학, 미적분학 등의 기본 개념을 기반으로 다양한 수치 연산을 적용하는 방법 등 실습 딥러닝에 필요한 전제 조건을 빠르게 소개합니다. 그리고 확률. 섹션 3과 섹션 5에서는 회귀 및 분류를 포함하여 딥러닝의 가장 기본적인 개념과 기술을 다룹니다. 선형 모델; 다층 퍼셉트론; 그리고 과적합과 정규화.

 

  • Part 2: Modern Deep Learning Techniques. Section 6 describes the key computational components of deep learning systems and lays the groundwork for our subsequent implementations of more complex models. Next, Section 7 and Section 8 present convolutional neural networks (CNNs), powerful tools that form the backbone of most modern computer vision systems. Similarly, Section 9 and Section 10 introduce recurrent neural networks (RNNs), models that exploit sequential (e.g., temporal) structure in data and are commonly used for natural language processing and time series prediction. In Section 11, we describe a relatively new class of models, based on so-called attention mechanisms, that has displaced RNNs as the dominant architecture for most natural language processing tasks. These sections will bring you up to speed on the most powerful and general tools that are widely used by deep learning practitioners.

2부: 최신 딥 러닝 기술. 섹션 6에서는 딥 러닝 시스템의 주요 계산 구성 요소를 설명하고 보다 복잡한 모델의 후속 구현을 위한 토대를 마련합니다. 다음으로 섹션 7과 섹션 8에서는 대부분의 최신 컴퓨터 비전 시스템의 백본을 형성하는 강력한 도구인 CNN(컨볼루션 신경망)을 소개합니다. 마찬가지로 섹션 9와 섹션 10에서는 데이터의 순차(예: 시간) 구조를 활용하고 자연어 처리 및 시계열 예측에 일반적으로 사용되는 모델인 순환 신경망(RNN)을 소개합니다. 섹션 11에서는 대부분의 자연어 처리 작업에 대한 지배적인 아키텍처로 RNN을 대체한 소위 attention 메커니즘을 기반으로 하는 상대적으로 새로운 클래스의 모델을 설명합니다. 이 섹션에서는 딥 러닝 실무자가 널리 사용하는 가장 강력하고 일반적인 도구를 빠르게 소개합니다.

 

  • Part 3: Scalability, Efficiency, and Applications (available online). In Chapter 12, we discuss several common optimization algorithms used to train deep learning models. Next, in Chapter 13, we examine several key factors that influence the computational performance of deep learning code. Then, in Chapter 14, we illustrate major applications of deep learning in computer vision. Finally, in Chapter 15 and Chapter 16, we demonstrate how to pretrain language representation models and apply them to natural language processing tasks.

3부: 확장성, 효율성 및 애플리케이션(온라인으로 제공) 12장에서는 딥러닝 모델을 훈련하는 데 사용되는 몇 가지 일반적인 최적화 알고리즘에 대해 논의합니다. 다음으로 13장에서는 딥러닝 코드의 계산 성능에 영향을 미치는 몇 가지 핵심 요소를 살펴봅니다. 그런 다음 14장에서는 컴퓨터 비전에 딥러닝을 적용하는 방법을 설명합니다. 마지막으로 15장과 16장에서는 언어 표현 모델을 사전 훈련하고 이를 자연어 처리 작업에 적용하는 방법을 보여줍니다.

 

Code

Most sections of this book feature executable code. We believe that some intuitions are best developed via trial and error, tweaking the code in small ways and observing the results. Ideally, an elegant mathematical theory might tell us precisely how to tweak our code to achieve a desired result. However, deep learning practitioners today must often tread where no solid theory provides guidance. Despite our best attempts, formal explanations for the efficacy of various techniques are still lacking, for a variety of reasons: the mathematics to characterize these models can be so difficult; the explanation likely depends on properties of the data that currently lack clear definitions; and serious inquiry on these topics has only recently kicked into high gear. We are hopeful that as the theory of deep learning progresses, each future edition of this book will provide insights that eclipse those presently available.

 

이 책의 대부분의 섹션에는 실행 가능한 코드가 포함되어 있습니다. 우리는 시행착오를 통해 일부 직관이 가장 잘 개발되고, 코드를 작은 방식으로 조정하고 결과를 관찰한다고 믿습니다. 이상적으로, 우아한 수학 이론은 원하는 결과를 얻기 위해 코드를 조정하는 방법을 정확하게 알려줄 수 있습니다. 그러나 오늘날 딥 러닝 실무자들은 확실한 이론이 지침을 제공하지 않는 곳을 자주 밟아야 합니다. 최선의 노력에도 불구하고 다양한 기술의 효능에 대한 공식적인 설명은 여러 가지 이유로 여전히 부족합니다. 이러한 모델을 특성화하는 수학은 매우 어려울 수 있습니다. 설명은 현재 명확한 정의가 부족한 데이터의 속성에 따라 달라질 수 있습니다. 이러한 주제에 대한 진지한 조사는 최근에야 본격적으로 시작되었습니다. 우리는 딥러닝 이론이 발전함에 따라 이 책의 향후 버전이 현재 제공되는 통찰력을 능가하는 통찰력을 제공할 것이라는 희망을 갖고 있습니다.

 

To avoid unnecessary repetition, we capture some of our most frequently imported and used functions and classes in the d2l package. Throughout, we mark blocks of code (such as functions, classes, or collection of import statements) with #@save to indicate that they will be accessed later via the d2l package. We offer a detailed overview of these classes and functions in Section 23.8. The d2l package is lightweight and only requires the following dependencies:

 

불필요한 반복을 피하기 위해 가장 자주 가져오고 사용되는 함수와 클래스 중 일부를 d2l 패키지에 캡처합니다. 전체적으로 코드 블록(예: 함수, 클래스 또는 import 문 모음)을 #@save로 표시하여 나중에 d2l 패키지를 통해 액세스할 것임을 나타냅니다. 섹션 23.8에서 이러한 클래스와 함수에 대한 자세한 개요를 제공합니다. d2l 패키지는 경량이며 다음 종속성만 필요합니다.

 

#@save
import collections
import hashlib
import inspect
import math
import os
import random
import re
import shutil
import sys
import tarfile
import time
import zipfile
from collections import defaultdict
import pandas as pd
import requests
from IPython import display
from matplotlib import pyplot as plt
from matplotlib_inline import backend_inline

d2l = sys.modules[__name__]

 

Most of the code in this book is based on PyTorch, a popular open-source framework that has been enthusiastically embraced by the deep learning research community. All of the code in this book has passed tests under the latest stable version of PyTorch. However, due to the rapid development of deep learning, some code in the print edition may not work properly in future versions of PyTorch. We plan to keep the online version up to date. In case you encounter any problems, please consult Installation to update your code and runtime environment. Below lists dependencies in our PyTorch implementation.

 

이 책에 있는 대부분의 코드는 딥 러닝 연구 커뮤니티에서 열광적으로 수용한 인기 오픈 소스 프레임워크인 PyTorch를 기반으로 합니다. 이 책의 모든 코드는 PyTorch의 최신 안정 버전에서 테스트를 통과했습니다. 그러나 딥러닝의 급속한 발전으로 인해 인쇄판의 일부 코드가 향후 버전의 PyTorch에서 제대로 작동하지 않을 수 있습니다. 우리는 온라인 버전을 최신 상태로 유지할 계획입니다. 문제가 발생하는 경우 설치를 참조하여 코드와 런타임 환경을 업데이트하세요. 아래에는 PyTorch 구현의 종속성이 나열되어 있습니다.

 

#@save
import numpy as np
import torch
import torchvision
from PIL import Image
from scipy.spatial import distance_matrix
from torch import nn
from torch.nn import functional as F
from torchvision import transforms

 

Target Audience

This book is for students (undergraduate or graduate), engineers, and researchers, who seek a solid grasp of the practical techniques of deep learning. Because we explain every concept from scratch, no previous background in deep learning or machine learning is required. Fully explaining the methods of deep learning requires some mathematics and programming, but we will only assume that you enter with some basics, including modest amounts of linear algebra, calculus, probability, and Python programming. Just in case you have forgotten anything, the online Appendix provides a refresher on most of the mathematics you will find in this book. Usually, we will prioritize intuition and ideas over mathematical rigor. If you would like to extend these foundations beyond the prerequisites to understand our book, we happily recommend some other terrific resources: Linear Analysis by Bollobás (1999) covers linear algebra and functional analysis in great depth. All of Statistics (Wasserman, 2013) provides a marvelous introduction to statistics. Joe Blitzstein’s books and courses on probability and inference are pedagogical gems. And if you have not used Python before, you may want to peruse this Python tutorial.

 

이 책은 딥러닝의 실용적인 기술을 확실하게 이해하려는 학생(학부 또는 대학원), 엔지니어, 연구원을 위한 책입니다. 모든 개념을 처음부터 설명하기 때문에 딥 러닝이나 머신 러닝에 대한 사전 배경 지식이 필요하지 않습니다. 딥 러닝 방법을 완전히 설명하려면 약간의 수학과 프로그래밍이 필요하지만, 적당한 양의 선형 대수학, 미적분학, 확률 및 Python 프로그래밍을 포함한 몇 가지 기본 지식만 갖추고 있다고 가정합니다. 잊어버린 내용이 있을 경우를 대비해 온라인 부록을 통해 이 책에서 찾을 수 있는 대부분의 수학에 대해 다시 한 번 복습해 보세요. 일반적으로 우리는 수학적 엄격함보다 직관과 아이디어를 우선시합니다. 우리 책을 이해하기 위해 전제 조건 이상으로 이러한 기초를 확장하고 싶다면 다른 훌륭한 자료를 기꺼이 추천합니다. Bollobás의 선형 분석(1999)은 선형 대수학 및 함수 분석을 매우 깊이 다루고 있습니다. All of Statistics(Wasserman, 2013)는 통계에 대한 놀라운 소개를 제공합니다. 확률과 추론에 관한 Joe Blitzstein의 책과 강좌는 교육학적 보석입니다. 이전에 Python을 사용해 본 적이 없다면 이 Python 튜토리얼을 정독하는 것이 좋습니다.

 

Notebooks, Website, GitHub, and Forum

All of our notebooks are available for download on the D2L.ai website and on GitHub. Associated with this book, we have launched a discussion forum, located at discuss.d2l.ai. Whenever you have questions on any section of the book, you can find a link to the associated discussion page at the end of each notebook.

 

모든 노트북은 D2L.ai 웹사이트와 GitHub에서 다운로드할 수 있습니다. 이 책과 관련하여 우리는 토론 포럼(discuss.d2l.ai)을 시작했습니다. 책의 어떤 섹션에 대해 질문이 있을 때마다 각 노트북 끝에 있는 관련 토론 페이지에 대한 링크를 찾을 수 있습니다.

 

Acknowledgments

We are indebted to the hundreds of contributors for both the English and the Chinese drafts. They helped improve the content and offered valuable feedback. This book was originally implemented with MXNet as the primary framework. We thank Anirudh Dagar and Yuan Tang for adapting a majority part of earlier MXNet code into PyTorch and TensorFlow implementations, respectively. Since July 2021, we have redesigned and reimplemented this book in PyTorch, MXNet, and TensorFlow, choosing PyTorch as the primary framework. We thank Anirudh Dagar for adapting a majority part of more recent PyTorch code into JAX implementations. We thank Gaosheng Wu, Liujun Hu, Ge Zhang, and Jiehang Xie from Baidu for adapting a majority part of more recent PyTorch code into PaddlePaddle implementations in the Chinese draft. We thank Shuai Zhang for integrating the LaTeX style from the press into the PDF building.

 

우리는 영어와 중국어 초안 모두에 기여한 수백 명의 기고자들에게 빚을 지고 있습니다. 그들은 콘텐츠 개선에 도움을 주고 귀중한 피드백을 제공했습니다. 이 책은 원래 MXNet을 기본 프레임워크로 구현했습니다. 이전 MXNet 코드의 대부분을 각각 PyTorch 및 TensorFlow 구현에 적용한 Anirudh Dagar와 Yuan Tang에게 감사드립니다. 2021년 7월부터 우리는 PyTorch, MXNet, TensorFlow에서 이 책을 재설계하고 구현했으며 PyTorch를 기본 프레임워크로 선택했습니다. 최신 PyTorch 코드의 대부분을 JAX 구현에 적용한 Anirudh Dagar에게 감사드립니다. 최신 PyTorch 코드의 대부분을 중국 초안의 PaddlePaddle 구현에 적용한 Baidu의 Gaosheng Wu, Liujun Hu, Ge Zhang 및 Jiehang Xie에게 감사드립니다. 언론의 LaTeX 스타일을 PDF 건물에 통합한 Shuai Zhang에게 감사드립니다.

 

On GitHub, we thank every contributor of this English draft for making it better for everyone. Their GitHub IDs or names are (in no particular order): alxnorden, avinashingit, bowen0701, brettkoonce, Chaitanya Prakash Bapat, cryptonaut, Davide Fiocco, edgarroman, gkutiel, John Mitro, Liang Pu, Rahul Agarwal, Mohamed Ali Jamaoui, Michael (Stu) Stewart, Mike Müller, NRauschmayr, Prakhar Srivastav, sad-, sfermigier, Sheng Zha, sundeepteki, topecongiro, tpdi, vermicelli, Vishaal Kapoor, Vishwesh Ravi Shrimali, YaYaB, Yuhong Chen, Evgeniy Smirnov, lgov, Simon Corston-Oliver, Igor Dzreyev, Ha Nguyen, pmuens, Andrei Lukovenko, senorcinco, vfdev-5, dsweet, Mohammad Mahdi Rahimi, Abhishek Gupta, uwsd, DomKM, Lisa Oakley, Bowen Li, Aarush Ahuja, Prasanth Buddareddygari, brianhendee, mani2106, mtn, lkevinzc, caojilin, Lakshya, Fiete Lüer, Surbhi Vijayvargeeya, Muhyun Kim, dennismalmgren, adursun, Anirudh Dagar, liqingnz, Pedro Larroy, lgov, ati-ozgur, Jun Wu, Matthias Blume, Lin Yuan, geogunow, Josh Gardner, Maximilian Böther, Rakib Islam, Leonard Lausen, Abhinav Upadhyay, rongruosong, Steve Sedlmeyer, Ruslan Baratov, Rafael Schlatter, liusy182, Giannis Pappas, ati-ozgur, qbaza, dchoi77, Adam Gerson, Phuc Le, Mark Atwood, christabella, vn09, Haibin Lin, jjangga0214, RichyChen, noelo, hansent, Giel Dops, dvincent1337, WhiteD3vil, Peter Kulits, codypenta, joseppinilla, ahmaurya, karolszk, heytitle, Peter Goetz, rigtorp, Tiep Vu, sfilip, mlxd, Kale-ab Tessera, Sanjar Adilov, MatteoFerrara, hsneto, Katarzyna Biesialska, Gregory Bruss, Duy–Thanh Doan, paulaurel, graytowne, Duc Pham, sl7423, Jaedong Hwang, Yida Wang, cys4, clhm, Jean Kaddour, austinmw, trebeljahr, tbaums, Cuong V. Nguyen, pavelkomarov, vzlamal, NotAnotherSystem, J-Arun-Mani, jancio, eldarkurtic, the-great-shazbot, doctorcolossus, gducharme, cclauss, Daniel-Mietchen, hoonose, biagiom, abhinavsp0730, jonathanhrandall, ysraell, Nodar Okroshiashvili, UgurKap, Jiyang Kang, StevenJokes, Tomer Kaftan, liweiwp, netyster, ypandya, NishantTharani, heiligerl, SportsTHU, Hoa Nguyen, manuel-arno-korfmann-webentwicklung, aterzis-personal, nxby, Xiaoting He, Josiah Yoder, mathresearch, mzz2017, jroberayalas, iluu, ghejc, BSharmi, vkramdev, simonwardjones, LakshKD, TalNeoran, djliden, Nikhil95, Oren Barkan, guoweis, haozhu233, pratikhack, Yue Ying, tayfununal, steinsag, charleybeller, Andrew Lumsdaine, Jiekui Zhang, Deepak Pathak, Florian Donhauser, Tim Gates, Adriaan Tijsseling, Ron Medina, Gaurav Saha, Murat Semerci, Lei Mao, Levi McClenny, Joshua Broyde, jake221, jonbally, zyhazwraith, Brian Pulfer, Nick Tomasino, Lefan Zhang, Hongshen Yang, Vinney Cavallo, yuntai, Yuanxiang Zhu, amarazov, pasricha, Ben Greenawald, Shivam Upadhyay, Quanshangze Du, Biswajit Sahoo, Parthe Pandit, Ishan Kumar, HomunculusK, Lane Schwartz, varadgunjal, Jason Wiener, Armin Gholampoor, Shreshtha13, eigen-arnav, Hyeonggyu Kim, EmilyOng, Bálint Mucsányi, Chase DuBois, Juntian Tao, Wenxiang Xu, Lifu Huang, filevich, quake2005, nils-werner, Yiming Li, Marsel Khisamutdinov, Francesco “Fuma” Fumagalli, Peilin Sun, Vincent Gurgul, qingfengtommy, Janmey Shukla, Mo Shan, Kaan Sancak, regob, AlexSauer, Gopalakrishna Ramachandra, Tobias Uelwer, Chao Wang, Tian Cao, Nicolas Corthorn, akash5474, kxxt, zxydi1992, Jacob Britton, Shuangchi He, zhmou, krahets, Jie-Han Chen, Atishay Garg, Marcel Flygare, adtygan, Nik Vaessen, bolded, Louis Schlessinger, Balaji Varatharajan, atgctg, Kaixin Li, Victor Barbaros, Riccardo Musto, Elizabeth Ho, azimjonn, Guilherme Miotto, Alessandro Finamore, Joji Joseph, Anthony Biel, Zeming Zhao, shjustinbaek, gab-chen, nantekoto, Yutaro Nishiyama, Oren Amsalem, Tian-MaoMao, Amin Allahyar, Gijs van Tulder, Mikhail Berkov, iamorphen, Matthew Caseres, Andrew Walsh, pggPL, RohanKarthikeyan, Ryan Choi, and Likun Lei.

 

GitHub에서는 이 영어 초안을 모두에게 더 좋게 만들어 준 모든 기여자에게 감사드립니다. 해당 GitHub ID 또는 이름은 다음과 같습니다(특정 순서 없음):  alxnorden, avinashingit, bowen0701, brettkoonce, Chaitanya Prakash Bapat, cryptonaut, Davide Fiocco, edgarroman, gkutiel, John Mitro, Liang Pu, Rahul Agarwal, Mohamed Ali Jamaoui, Michael(Stu ) Stewart, Mike Müller, NRauschmayr, Prakhar Srivastav, sad-, sfermigier, Sheng Zha, sundeepteki, topecongiro, tpdi, vermicelli, Vishaal Kapoor, Vishwesh Ravi Shrimali, YaYaB, Yuhong Chen, Evgeniy Smirnov, lgov, Simon Corston-Oliver, Igor Dzreyev, Ha Nguyen, pmuens, Andrei Lukovenko, senorcinco, vfdev-5, dsweet, Mohammad Mahdi Rahimi, Abhishek Gupta, uwsd, DomKM, Lisa Oakley, Bowen Li, Aarush Ahuja, Prasanth Buddareddygari, brianhendee, mani2106, mtn, lkevinzc, caojilin , Lakshya, Fiete Lüer, Surbhi Vijayvargeeya, 김무현, dennismalmgren, adursun, Anirudh Dagar, liqingnz, Pedro Larroy, lgov, ati-ozgur, Jun Wu, Matthias Blume, Lin Yuan, geogunow, Josh Gardner, Maximilian Böther, Rakib Islam, Leonard Lausen, Abhinav Upadhyay, rongruosong, Steve Sedlmeyer, Ruslan Baratov, Rafael Schlatter, liusy182, Giannis Pappas, ati-ozgur, qbaza, dchoi77, Adam Gerson, Phuc Le, Mark Atwood, christabella, vn09, Haibin Lin, jjangga0214, RichyChen, noelo, hansent, Giel Dops, dvincent1337, WhiteD3vil, Peter Kulits, codypenta, joseppinilla, ahmaurya, karolszk, heytitle, Peter Goetz, rigtorp, Tiep Vu, sfilip, mlxd, Kale-ab Tessera, Sanjar Adilov, MatteoFerrara, hsneto, Katarzyna Biesialska , Gregory Bruss, Duy–Thanh Doan, paulaurel, greytowne, Duc Pham, sl7423, Jaedong Hwang, Yida Wang, cys4, clhm, Jean Kaddour, austinmw, trebeljahr, tbaums, Cuong V. Nguyen, pavelkomarov, vzlamal, NotAnotherSystem, J- Arun-Mani, jancio, eldarkurtic, the-great-shazbot, doctorcolossus, gducharme, clauss, Daniel-Mietchen, hoonose, biagiom, abhinavsp0730, jonathanhrandall, ysraell, Nodar Okroshiashvili, UgurKap, 강지양, StevenJokes, Tomer Kaftan, liweiwp, netyster , ypandya, NishantTharani, heiligerl, SportsTHU, Hoa Nguyen, manuel-arno-korfmann-webentwicklung, aterzis-personal, nxby, Xiaoting He, Josiah Yoder, mathresearch, mzz2017, jroberayalas, iluu, ghejc, BSharmi, vkramdev, simonwardjones, LakshKD, TalNeoran, djliden, Nikhil95, Oren Barkan, guoweis, haozhu233, pratikhack, Yue Ying, tayfununal, steinsag, charleybeller, Andrew Lumsdaine, Jiekui Zhang, Deepak Pathak, Florian Donhauser, Tim Gates, Adriaan Tijsseling, Ron Medina, Gaurav Saha, Murat Semerci , Lei Mao, Levi McClenny, Joshua Broyde, jake221, jonbally, zyhazwraith, Brian Pulfer, Nick Tomasino, Lefan Zhang, Hongshen Yang, Vinney Cavallo, yuntai, Yuanxiang Zhu, amarazov, pasricha, Ben Greenawald, Shivam Upadhyay, Quanshangze Du, Biswajit Sahoo, Parthe Pandit, Ishan Kumar, HomunculusK, Lane Schwartz, varadgunjal, Jason Wiener, Armin Gholampoor, Shreshtha13, eigen-arnav, 김형규, EmilyOng, Bálint Mucsányi, Chase DuBois, Juntian Tao, Wenxiang Xu, Lifu Huang, filevich, quake2005 , nils-werner, Yiming Li, Marsel Khisamutdinov, Francesco “Fuma” Fumagalli, Peilin Sun, Vincent Gurgul, qingfengtommy, Janmey Shukla, Mo Shan, Kaan Sancak, regob, AlexSauer, Gopalakrishna Ramachandra, Tobias Uelwer, Chao Wang, Tian Cao, Nicolas Corthorn, akash5474, kxxt, zxydi1992, Jacob Britton, Shuangchi He, zhmou, krahets, Jie-Han Chen, Atishay Garg, Marcel Flygare, adtygan, Nik Vaessen, 굵은 글씨체, Louis Schlessinger, Balaji Varatharajan, atgctg, Kaixin Li, Victor Barbaros , Riccardo Musto, Elizabeth Ho, azimjonn, Guilherme Miotto, Alessandro Finamore, Joji Joseph, Anthony Biel, Zeming Zhao, shjustinbaek, gab-chen, nantekoto, 니시야마 유타로, Oren Amsalem, Tian-MaoMao, Amin Allahyar, Gijs van Tulder, Mikhail Berkov, iamorphen, Matthew Caseres, Andrew Walsh, pggPL, RohanKarthikeyan, Ryan Choi 및 Likun Lei.

 

We thank Amazon Web Services, especially Wen-Ming Ye, George Karypis, Swami Sivasubramanian, Peter DeSantis, Adam Selipsky, and Andrew Jassy for their generous support in writing this book. Without the available time, resources, discussions with colleagues, and continuous encouragement, this book would not have happened. During the preparation of the book for publication, Cambridge University Press has offered excellent support. We thank our commissioning editor David Tranah for his help and professionalism.

 

Amazon Web Services, 특히 이 책을 집필하는 데 아낌없는 지원을 해주신 Wen-Ming Ye, George Karypis, Swami Sivasubramanian, Peter DeSantis, Adam Selipsky 및 Andrew Jassy에게 감사드립니다. 가용한 시간, 자원, 동료와의 토론, 지속적인 격려가 없었다면 이 책은 탄생하지 못했을 것입니다. 출판을 위한 책을 준비하는 동안 Cambridge University Press는 훌륭한 지원을 제공했습니다. 우리의 커미셔닝 편집자 David Tranah의 도움과 전문성에 감사드립니다.

 

Summary

Deep learning has revolutionized pattern recognition, introducing technology that now powers a wide range of technologies, in such diverse fields as computer vision, natural language processing, and automatic speech recognition. To successfully apply deep learning, you must understand how to cast a problem, the basic mathematics of modeling, the algorithms for fitting your models to data, and the engineering techniques to implement it all. This book presents a comprehensive resource, including prose, figures, mathematics, and code, all in one place.

 

딥 러닝은 컴퓨터 비전, 자연어 처리, 자동 음성 인식 등 다양한 분야에서 광범위한 기술을 지원하는 기술을 도입하여 패턴 인식에 혁명을 일으켰습니다. 딥러닝을 성공적으로 적용하려면 문제를 캐스팅하는 방법, 모델링의 기본 수학, 모델을 데이터에 맞추는 알고리즘, 그리고 이를 모두 구현하는 엔지니어링 기술을 이해해야 합니다. 이 책은 산문, 그림, 수학, 코드를 포함한 포괄적인 리소스를 한 곳에서 제공합니다.

 

Exercises

 

  1. Register an account on the discussion forum of this book discuss.d2l.ai.
    이 책 Discuss.d2l.ai의 토론 포럼에 계정을 등록하세요.

  2. Install Python on your computer.
    컴퓨터에 Python을 설치합니다.

  3. Follow the links at the bottom of the section to the forum, where you will be able to seek out help and discuss the book and find answers to your questions by engaging the authors and broader community.
    섹션 하단에 있는 포럼 링크를 따라가면 도움을 받을 수 있고 책에 대해 토론할 수 있으며 저자 및 더 넓은 커뮤니티에 참여하여 질문에 대한 답변을 찾을 수 있습니다.

 

 

반응형

'Dive into Deep Learning > D2L Preface Installation Notation Intro' 카테고리의 다른 글

D2L - Introduction  (0) 2023.10.09
D2L - Installation  (0) 2023.10.08
D2L - Notation  (0) 2023.10.08


반응형

요즘 페북 친구들이 송이버섯을 땄다는 얘기가 종종 올라온다.

 

그래서 내 송이버섯 장소를 한번 둘러 보기로 했다.

내가 주로 가는 장소는 그렇게 높지 않아서 송이버섯이 좀 늦게 올라오는 편이다.

그래서 별 기대 없이 갔다. 산에는 송이버섯만 있는게 아니니까....

 

내가 주로 가는 곳은 시애틀에서 남쪽으로 1시간 반 정도 거리에 있는 레이니어 산이다.

백두산에 한라산 얹어 놓은 만큼 높은 산이다. 4400 미터 정도 된다. 

백두산 높이는 2744미터 한라산 높이는 1950미터이다.

 

레이니어산 정상 부근은 항상 눈이 덮여 있다.

 

나의 송이버섯 spots는 레이니어산 남쪽 고도 2000 피트 정도이다.

미터로는 600미터 조금 넘는다.

 

역시나 짐작대로 송이버섯은 아직.

하지만 맛있는 꾀꼬리 버섯(Chanterelle mushrooms)들이 많이 있었다.

 

이 꾀꼬리 버섯들을 조금 따서 집에 오자마자 볶아서 반찬으로 만들어 뒀다.

 

내가 주로 가는 장소는 10월 중순이 지나야 송이가 올라올 것 같다.

 

Last week, I headed down to my favorite Matsutake mushroom hunting grounds, located about 2,000 feet south of Mount Rainier. You see, that's where I usually find my Matsutake stash.

 

But guess what? It seems like it's still a tad too early for the Matsutakes to make their grand appearance. No worries, though!

 

Instead of Matsutake, we scored big with Chanterelle mushrooms and whipped up some seriously scrumptious dishes. Trust me, they hit the spot!

 

I've got a feeling that Matsutakes will be popping up around mid-October. So, the mushroom adventure continues!

 

https://youtu.be/E9nr1ufvnD8?si=twmygJhsm_HldfDh

 

 

 

 

 

 

 

 

 

반응형


반응형

내가 사는 올림피아 시는 워싱턴 주의 주도 입니다. 워싱턴 주는 시애틀이 있는 주이죠. 시애틀은 올림피아에서 1시간 거리에 있습니다.

 

주청사 옆에 경포대같이 바다와 통하는 호수가 있고 이 호수는 강이라고 하기에는 조금 작은 개천같은 곳에서 물이들어 옵니다. 이름은 Deschutes River라고 합니다.

매년 가을부터 초겨울까지 연어들이 바다에서 이 호수를 거쳐서 Deschutes River로 올라 갑니다.

이 Deschutes River 에는 Brewery Park이라고 있는데요. 예전에 이곳에 맥주 공장이 있었다고 합니다. 지금은 폐건물만 있고 그 주변을 공원으로 만들었습니다.

그 공원 안에 Tumwater Falls 라고 조그만 폭포가 있습니다.

이 곳에는 인공 구조물 때문에 연어가 오르기 힘든 곳이 있는데요. 연어들이 이곳을 피해서 갈 수 이도록 수로를 따로 만들었습니다.

이 수로 끝에는 Tumwater Falls Hatchery라는 연어 부화장이 있는데요.

이곳에 오는 연어들을 한곳에 모아서 인공 수정 후 어느 정도 기른 다음에 다시 놓아 주는 일을 합니다.

 

이곳에 가면 이 Hatchery 밑에서 연어들이 빠른 물살을 거꾸로 거슬러 오르는 모습을 볼 수 있는데요.

아주 장관입니다.

 

요 몇주일 사이에 세번 정도 이 Brewery Park에 가서 연어들이 물살을 거슬로 오르는 모습을 구경했습니다.

 

조그만 폭포가 군데 군데 있는데 그 폭포를 뛰어 오르려고 점프하는 연어들을 보면 정말 신기합니다.

 

https://youtube.com/shorts/3QfPmJ46zT0?si=zR7WOArOmlLpRUXd 

https://youtube.com/shorts/sP7HYeBMfY4?si=r6tCzqO24PVp-0LU 

 

조금 더 위로 올라가면 이 연어들을 한곳으로 모으는 수로도 있는데요.

이 수로에는 연어들로 가득합니다.

그리고 여기 오는 사람들이 보기 쉽게 벽을 유리로 만들어서 야생 연어가 지나가는 모습을 어항처럼 볼 수 있는 시설도 만들어서 아이들을 데이고 부모들이 많이 옵니다.

 

https://youtu.be/UTD4ilnAw20?si=O5eTKZRAQwy8taKj 

 

9월의 마지막날인 9월 30일 이곳에서는 Tumwater Falls Park Festival이 열렸습니다.

 

기념품들도 많이 팔고 관련 단체에서 나와서 홍보도 하고 아이들을 위해 연어의 생애같은 것도 교육해 주고 많은 프로그램들을 준비했더라구요.

 

https://youtu.be/SbnFkO7PY-U?si=ZmRWTmsjO8ZmCYro 

 

집에서 10분도 안걸리는 거리에 이런 좋은 장소가 있으서 자주 찾아옵니다.

특히 가을에는 연어를 보러 더 자주 오는 곳이죠.

 

가을 겨울 시애틀 여행하러 오시는 분들 중에 시간이 좀 되시는 분들은 워싱턴주의 주도인 올림피아도 한번 들러도 좋을거예요.

 

 

 

 

 

반응형


반응형

매 끼니 식사를 준비한다는 것은 빈 배를 채우는게 아니라 꽉찬 냉장고를 비우는 일이다.

 

마누라가 수술받으러 한국에 가서 혼자 미국 집 지키는 한국 남자가 한달간 집안 일 하면서 느낀 거다.

 

혼자 있으니까 음식들이 천천히 줄고 있다. 뭐 그래도 된다. 천천히 요리해서 먹으면 되지 뭐..

근데 야채가 생겼다.

양배추가호 양상추다.. 이건 느긋하게 기다리다가는 다 시들어 버릴 것 이다.

 

일단 소금에 절였다. 하루 동안.. 

소금에 절이는 동안 김치 만드는 법을 유투브에서 찾아보고...

거기 나온 재료 중 집에 있는 것들을 찾아 놨다.

 

양념사러 마트 가기도 귀찮다.

한국 마트는 차로 한시간이나 가야 한다.

 

고추가루, 간마늘, 설탕, 소금 등등 꼭 필요한 기본 재료는 있다.

그래서 김치를 만들었다.

 

뭐 집에 있는걸 대충 넣어서 그런지 김치 양념이 맛이 이상했지만... 그래도 뭐...

나는 깨달았다. 한국 음식은 고추가루의 매운맛과 소금의 짠 맛 그리고 설탕의 단맛들을 간마늘로 섞어 주면 대충 맛이 난다는 거..

내가한 김치가 못 먹을 정도는 아니다.

 

모처럼 큰 부엌일을 하는 김에 냉동고에 있던 닭한마리도 처리하기로 했다.

제일 간단한 닭요리인 백숙을 해 먹었다.

그냥 깨끗이 씻어서 물에 끓인 후 소금만 찍어 먹으면 됐다.

 

집안 일을 하다 보니까 일이 힘들지는 않은데... 무수히 많은 잡일과 자잘한 일들이 넘쳐 났다.

일 마치고 의자에 앉자마자 생각이 나서 0.1초만에 엉덩이 다시 띠고 잡일 처리하고 다시 의자에 않는 과정이 하루 종일 반복된다.

 

그리고 수많은 자잘한 일들이 많아서 이것 저것 자꾸 까먹게 된다.

 

며칠전에는 한국 영사관에서 F4 비자를 바는데 필요한 FBI 범죄 경력 증명서를 미국 정부 공증을 받는 아포스티유라는 것을 했다.

아포스티유 양식과 FBI 범죄 경력 증명서를 버지니아에 있는 담당 부서에 보내야 하는데 깜빡 잊고 제일 중요한 FBI 범죄 경력 증명서 문서를 안 넣은 것이다.

 

다행히 1980년도에 내 고향인 춘천에 있던 미군기지 Camp Page 에서 근무했었다는 우체국 직원이 친절하게 잘 응대해 줘서 다시 우편 봉투를 찾고 뜯어서 미싱한 문서 넣고 다시 테이프로 붙여서 보낼 수 있었다.

 

집안일 하다보면 이렇게 되는구나...

매번 마누라가 이런 자잘한 실수 할 때무다 뭐라고 쿠사리 줬었는데.. 나도 똑같아 지네....

 

오늘의 교훈...

다른 사람 눈에 안 찬다고 뭐라 그러지 마라... 다 그럴만한 이유가 있어서 그러는 걸거다....

 

https://youtu.be/w8CXSDAxiH0?si=_NVuXPAL1iwyNMGc 

 

이날의 메뉴... 닭백숙, 샐한 김치.. 남은 김치 양념에 비빈 비빔밥...

 

반응형


반응형

시애틀이 있는 이곳 워싱턴 주의 레이저 클램 시즌이 시작된다.

WDFW는 9월 26일부터 워싱턴 주 태평양 해안에서의 태평양 맛조개 (Razor Clam) 채취를 허용한다고 발표 했다.

 

지난 주말이나 9월 16일 Federal Way 에서는 근처에 사는 30여명의 한인들이 후쿠시마 핵 오염수 방류 중단을 요구하는 시위를 했다.

 

이날 구호는 Stop Dumping Nuclear waste water 였다.

언론에서는 Nuclear waste water를 Radioactive water 라고 한다.

 

이곳 주류 언론에서는 미국 정부의 공식 입장이 안전하다는 거여서 그렇게 크게 다루지는 않는다.

 

나는 바다 낚시와 조개, 굴 채취를 좋아 하는 사람으로서 걱정이 돼서 그 집회에 참가 했다.

 

해류를 타고 미국 서부 해안인 이곳 워싱턴주까지 오는데 한 1년도 한 걸릴 것 같다.

WDFW에서는 바닷물에 대한 수질 검사를 하고 그 상황을 인터넷에 공유를 하는데 방사능 관련 지표도 정기 검사에 추가 하라고 요구해야 겠다.

 

 

 

https://youtu.be/QrpLyd8ONwM?si=HWr7MfsSyVQPYw-F 

 

반응형


반응형

20.2. Deep Convolutional Generative Adversarial Networks — Dive into Deep Learning 1.0.3 documentation (d2l.ai)

 

20.2. Deep Convolutional Generative Adversarial Networks — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

20.2. Deep Convolutional Generative Adversarial Networks

In Section 20.1, we introduced the basic ideas behind how GANs work. We showed that they can draw samples from some simple, easy-to-sample distribution, like a uniform or normal distribution, and transform them into samples that appear to match the distribution of some dataset. And while our example of matching a 2D Gaussian distribution got the point across, it is not especially exciting.

 

섹션 20.1에서 GAN 작동 방식에 대한 기본 아이디어를 소개했습니다. 우리는 균일 분포 또는 정규 분포와 같이 간단하고 샘플링하기 쉬운 분포에서 샘플을 추출하여 일부 데이터 세트의 분포와 일치하는 것처럼 보이는 샘플로 변환할 수 있음을 보여주었습니다. 2D 가우스 분포를 일치시키는 예제는 요점을 이해했지만 특별히 흥미롭지는 않습니다.

 

In this section, we will demonstrate how you can use GANs to generate photorealistic images. We will be basing our models on the deep convolutional GANs (DCGAN) introduced in Radford et al. (2015). We will borrow the convolutional architecture that have proven so successful for discriminative computer vision problems and show how via GANs, they can be leveraged to generate photorealistic images.

 

이 섹션에서는 GAN을 사용하여 사실적인 이미지를 생성하는 방법을 보여줍니다. 우리는 Radford 등이 소개한 DCGAN(Deep Convolutional GAN)을 모델의 기반으로 삼을 것입니다. (2015). 우리는 차별적인 컴퓨터 비전 문제에 대해 매우 성공적인 것으로 입증된 컨벌루션 아키텍처를 빌려 GAN을 통해 어떻게 활용하여 사실적인 이미지를 생성할 수 있는지 보여줄 것입니다.

 

import warnings
import torch
import torchvision
from torch import nn
from d2l import torch as d2l
  1. import warnings: 경고 메시지를 관리하기 위한 파이썬 내장 모듈인 warnings를 가져옵니다. 이 모듈은 경고를 표시하거나 숨기는 데 사용됩니다.
  2. import torch: 파이토치(PyTorch) 라이브러리를 가져옵니다. 파이토치는 딥러닝 모델을 구축하고 훈련하기 위한 인기 있는 라이브러리입니다.
  3. import torchvision: 파이토치와 함께 제공되는 torchvision 라이브러리를 가져옵니다. torchvision은 컴퓨터 비전 작업을 위한 데이터셋, 모델 아키텍처, 변환 등을 제공합니다.
  4. from torch import nn: 파이토치의 nn 모듈에서 Neural Network 모델과 관련된 클래스 및 함수를 가져옵니다. 이 모듈을 사용하여 다양한 뉴럴 네트워크 레이어를 정의하고 모델을 구성할 수 있습니다.
  5. from d2l import torch as d2l: D2L 라이브러리에서 파이토치 관련 기능을 가져옵니다. D2L은 Dive into Deep Learning 책의 학습 자료와 함께 제공되는 라이브러리로, 딥러닝 모델의 이해와 구현을 돕는 데 사용됩니다.

이 코드는 딥러닝 모델을 구축하고 훈련하기 위해 필요한 라이브러리와 모듈을 가져오는 부분으로, 이후의 코드에서 이러한 라이브러리와 모듈을 사용하여 모델을 구현하고 훈련할 것입니다.

 

20.2.1. The Pokemon Dataset

The dataset we will use is a collection of Pokemon sprites obtained from pokemondb. First download, extract and load this dataset.

 

우리가 사용할 데이터 세트는 pokemondb에서 얻은 포켓몬 스프라이트 모음입니다. 먼저 이 데이터세트를 다운로드하고 추출하고 로드하세요.

 

#@save
d2l.DATA_HUB['pokemon'] = (d2l.DATA_URL + 'pokemon.zip',
                           'c065c0e2593b8b161a2d7873e42418bf6a21106c')

data_dir = d2l.download_extract('pokemon')
pokemon = torchvision.datasets.ImageFolder(data_dir)
  1. d2l.DATA_HUB['pokemon'] = (d2l.DATA_URL + 'pokemon.zip', 'c065c0e2593b8b161a2d7873e42418bf6a21106c'): 이 코드 라인은 D2L 라이브러리의 데이터 허브(DATA_HUB)에 Pokemon 데이터셋의 URL과 해당 데이터의 해시 값을 등록합니다. 이를 통해 데이터를 다운로드하고 검증할 수 있습니다.
  2. data_dir = d2l.download_extract('pokemon'): d2l.download_extract 함수를 사용하여 Pokemon 데이터셋을 다운로드하고 압축을 해제한 후, 압축 해제된 데이터의 디렉토리 경로를 data_dir 변수에 저장합니다.
  3. pokemon = torchvision.datasets.ImageFolder(data_dir): 파이토치(torchvision)의 ImageFolder 데이터셋 클래스를 사용하여 data_dir에서 이미지 데이터를 읽어옵니다. 이 클래스는 이미지 데이터를 클래스별로 정리한 폴더 구조에서 데이터를 읽어옵니다. 예를 들어, 각 폴더는 하나의 클래스(라벨)를 나타내며 해당 클래스에 속하는 이미지 파일들을 해당 폴더에 저장합니다.

이 코드를 실행하면 Pokemon 데이터셋이 다운로드되고 파이토치 데이터셋 객체인 pokemon에 로드됩니다. 이후에는 이 데이터셋을 사용하여 딥러닝 모델을 학습하고 분류 등의 작업을 수행할 수 있습니다.

Downloading ../data/pokemon.zip from http://d2l-data.s3-accelerate.amazonaws.com/pokemon.zip...

 

We resize each image into 64×64. The ToTensor transformation will project the pixel value into [0,1], while our generator will use the tanh function to obtain outputs in [−1,1]. Therefore we normalize the data with 0.5 mean and 0.5 standard deviation to match the value range.

 

각 이미지의 크기를 64×64로 조정합니다. ToTensor 변환은 픽셀 값을 [0,1]에 투영하는 반면 생성기는 tanh 함수를 사용하여 [-1,1]의 출력을 얻습니다. 따라서 값 범위와 일치하도록 평균 0.5, 표준편차 0.5로 데이터를 정규화합니다.

 

batch_size = 256
transformer = torchvision.transforms.Compose([
    torchvision.transforms.Resize((64, 64)),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize(0.5, 0.5)
])
pokemon.transform = transformer
data_iter = torch.utils.data.DataLoader(
    pokemon, batch_size=batch_size,
    shuffle=True, num_workers=d2l.get_dataloader_workers())
  1. batch_size = 256: 미니배치의 크기를 설정합니다. 한 번에 처리할 데이터 샘플의 개수를 나타냅니다.
  2. transformer: 데이터 전처리를 위한 변환기(Transformer)를 정의합니다. 이 코드에서는 세 가지 변환을 연속적으로 적용합니다.
    • torchvision.transforms.Resize((64, 64)): 이미지의 크기를 (64, 64)로 조정합니다. 모든 이미지를 동일한 크기로 조정하여 모델에 입력으로 사용합니다.
    • torchvision.transforms.ToTensor(): 이미지를 파이토치 텐서로 변환합니다. 이는 이미지 데이터를 넘파이 배열에서 텐서로 변경하는 작업입니다.
    • torchvision.transforms.Normalize(0.5, 0.5): 이미지의 픽셀값을 정규화(normalize)합니다. 평균과 표준편차를 0.5로 설정하여 픽셀값을 -1에서 1 사이로 스케일링합니다.
  3. pokemon.transform = transformer: Pokemon 데이터셋의 전체 데이터에 대해 위에서 정의한 transformer를 적용합니다. 이제 데이터셋 내의 모든 이미지는 위의 변환을 거치게 됩니다.
  4. data_iter = torch.utils.data.DataLoader(pokemon, batch_size=batch_size, shuffle=True, num_workers=d2l.get_dataloader_workers()): torch.utils.data.DataLoader를 사용하여 데이터셋을 미니배치로 나누고 데이터 로딩을 관리합니다.
    • pokemon: 전처리된 Pokemon 데이터셋입니다.
    • batch_size: 미니배치의 크기를 설정합니다.
    • shuffle=True: 데이터를 에포크마다 섞습니다. 이것은 모델이 각 에포크에서 다양한 데이터를 볼 수 있도록 도와줍니다.
    • num_workers=d2l.get_dataloader_workers(): 데이터 로딩을 병렬로 처리할 워커(worker) 수를 설정합니다. 이렇게 하면 데이터 로딩이 빨라지며 훈련 속도를 향상시킬 수 있습니다.

이 코드를 실행하면 Pokemon 데이터셋이 전처리되고 미니배치 단위로 모델에 공급될 수 있는 형태로 준비됩니다. 이 데이터로더를 사용하여 훈련 및 검증 과정에서 모델을 훈련하고 테스트할 수 있습니다.

 

Let’s visualize the first 20 images.

 

처음 20개의 이미지를 시각화해 보겠습니다.

 

warnings.filterwarnings('ignore')
d2l.set_figsize((4, 4))
for X, y in data_iter:
    imgs = X[:20,:,:,:].permute(0, 2, 3, 1)/2+0.5
    d2l.show_images(imgs, num_rows=4, num_cols=5)
    break
  1. warnings.filterwarnings('ignore'): 이 코드 라인은 경고 메시지를 무시하도록 설정합니다. 데이터셋을 시각화할 때 발생할 수 있는 경고 메시지를 표시하지 않도록 합니다.
  2. d2l.set_figsize((4, 4)): 시각화된 이미지의 크기를 설정합니다. 이 경우에는 (4, 4) 크기로 설정되었습니다.
  3. for X, y in data_iter:: data_iter 데이터 로더를 통해 미니배치를 순회합니다. X는 이미지 데이터를, y는 해당 이미지의 라벨을 나타냅니다.
  4. imgs = X[:20,:,:,:].permute(0, 2, 3, 1)/2+0.5: 첫 번째 미니배치 중에서 처음 20개의 이미지 데이터를 선택하고, 차원 순서를 변경합니다. 원래 이미지의 차원 순서는 (배치 크기, 채널 수, 높이, 너비)이지만, 여기서는 (배치 크기, 높이, 너비, 채널 수)로 변경됩니다. 또한, 이미지의 픽셀값을 0.5를 더하고 2로 나누어 스케일을 조정합니다. 이로써 이미지의 픽셀값이 [0, 1] 범위로 스케일링됩니다.
  5. d2l.show_images(imgs, num_rows=4, num_cols=5): d2l.show_images 함수를 사용하여 이미지를 시각화합니다. imgs는 이미지 데이터의 배치를 나타내며, num_rows와 num_cols는 행과 열의 개수를 설정합니다. 이 경우에는 4x5 격자로 이미지가 표시됩니다.
  6. break: 첫 번째 미니배치를 시각화하고 나서 반복문을 종료합니다. 이 코드는 시각적으로 데이터셋의 일부를 확인할 수 있도록 도와줍니다.

이 코드를 실행하면 Pokemon 데이터셋에서 선택한 이미지 샘플이 시각화되어 출력됩니다. 이를 통해 데이터셋의 내용을 확인할 수 있습니다.

 

20.2.2. The Generator

The generator needs to map the noise variable z∈ℝ**d, a length-d vector, to a RGB image with width and height to be 64×64 . In Section 14.11 we introduced the fully convolutional network that uses transposed convolution layer (refer to Section 14.10) to enlarge input size. The basic block of the generator contains a transposed convolution layer followed by the batch normalization and ReLU activation.

 

생성기는 길이 d 벡터인 노이즈 변수 z∈ℝ**d를 너비와 높이가 64×64인 RGB 이미지에 매핑해야 합니다. 섹션 14.11에서 우리는 입력 크기를 확대하기 위해 전치 컨볼루션 레이어(섹션 14.10 참조)를 사용하는 완전 컨볼루션 네트워크를 소개했습니다. 생성기의 기본 블록에는 배치 정규화 및 ReLU 활성화가 뒤따르는 전치된 컨볼루션 레이어가 포함되어 있습니다.

 

class G_block(nn.Module):
    def __init__(self, out_channels, in_channels=3, kernel_size=4, strides=2,
                 padding=1, **kwargs):
        super(G_block, self).__init__(**kwargs)
        self.conv2d_trans = nn.ConvTranspose2d(in_channels, out_channels,
                                kernel_size, strides, padding, bias=False)
        self.batch_norm = nn.BatchNorm2d(out_channels)
        self.activation = nn.ReLU()

    def forward(self, X):
        return self.activation(self.batch_norm(self.conv2d_trans(X)))

이 클래스는 생성자 네트워크에서 사용되는 하나의 블록을 정의합니다. 블록은 ConvTranspose2d 레이어, BatchNorm2d 레이어, 그리고 ReLU 활성화 함수로 구성됩니다.

  • __init__ 메서드: 블록의 초기화를 담당합니다. 다양한 매개변수를 사용하여 ConvTranspose2d 레이어, BatchNorm2d 레이어, ReLU 활성화 함수를 생성합니다. 이 때, out_channels는 출력 채널 수, in_channels는 입력 채널 수, kernel_size는 컨볼루션 커널의 크기, strides는 스트라이드 값, padding은 패딩 값 등을 설정할 수 있습니다.
  • forward 메서드: 순전파를 정의합니다. 입력 데이터 X를 ConvTranspose2d 레이어, BatchNorm2d 레이어, ReLU 활성화 함수의 순서로 전파하여 출력을 반환합니다.

이 클래스를 사용하여 생성자 네트워크를 구축할 때, GAN 모델의 생성자는 여러 개의 G_block 레이어를 쌓아서 이미지를 생성합니다. 이러한 블록을 적절하게 조합하여 원하는 이미지를 생성하는 네트워크를 만들 수 있습니다.

 

 

In default, the transposed convolution layer uses a kℎ=kw=4 kernel, a sℎ=sw=2 strides, and a Pℎ=Pw=1 padding. With a input shape of n'h×n'w=16×16, the generator block will double input’s width and height.

 

기본적으로 전치 컨볼루션 레이어는 kℎ=kw=4 커널, sℎ=sw=2 스트라이드 및 Pℎ=Pw=1 패딩을 사용합니다. n'h×n'w=16×16의 입력 형태를 사용하면 생성기 블록은 입력의 너비와 높이를 두 배로 늘립니다.

 

x = torch.zeros((2, 3, 16, 16))
g_blk = G_block(20)
g_blk(x).shape
  1. x = torch.zeros((2, 3, 16, 16)): 2개의 샘플(batch size가 2), 3개의 채널(channel), 각각 16x16 크기의 이미지를 나타내는 4D 텐서를 생성합니다. 이 텐서는 가짜 이미지 생성을 위한 입력 데이터로 사용됩니다.
  2. g_blk = G_block(20): G_block 클래스를 사용하여 생성자 네트워크의 블록을 하나 생성합니다. 이 블록은 3D 텐서를 입력으로 받아 처리하고, 출력으로 3D 텐서를 생성합니다. 여기서 out_channels를 20으로 설정하여 출력 채널의 수를 20으로 정의합니다.
  3. g_blk(x).shape: 생성자 블록 g_blk에 입력 데이터 x를 전달하여 가짜 이미지를 생성합니다. 그리고 생성된 가짜 이미지의 크기(shape)를 확인합니다. 생성된 이미지의 크기를 확인하는 이유는 네트워크의 출력 크기를 이해하고 모델을 구성하기 위함입니다.

코드를 실행하면 g_blk를 사용하여 입력 데이터 x를 처리한 결과로 생성된 가짜 이미지의 크기(shape)를 확인할 수 있습니다. 이 예시에서는 출력 크기가 어떻게 결정되는지를 보여주기 위한 것이며, 실제 GAN 모델에서는 여러 개의 G_block 레이어를 조합하여 높은 해상도의 이미지를 생성하게 됩니다.

torch.Size([2, 20, 32, 32])

 

If changing the transposed convolution layer to a 4×4 kernel, 1×1 strides and zero padding. With a input size of 1×1, the output will have its width and height increased by 3 respectively.

 

전치된 컨볼루션 레이어를 4×4 커널로 변경하면 스트라이드는 1×1이고 패딩은 0입니다. 입력 크기가 1×1이면 출력의 너비와 높이가 각각 3씩 증가합니다.

 

x = torch.zeros((2, 3, 1, 1))
g_blk = G_block(20, strides=1, padding=0)
g_blk(x).shape

코드는 생성자 네트워크의 G_block 클래스를 사용하여 가짜 이미지를 생성하는 예시를 더 자세히 설명합니다. 이번에는 스트라이드(strides)와 패딩(padding)을 다르게 설정하여 어떻게 영향을 미치는지를 보여줍니다.

  1. x = torch.zeros((2, 3, 1, 1)): 2개의 샘플(batch size가 2), 3개의 채널(channel), 각각 1x1 크기의 이미지를 나타내는 4D 텐서를 생성합니다. 이 텐서는 가짜 이미지 생성을 위한 입력 데이터로 사용됩니다. 이번에는 이미지 크기가 1x1로 매우 작습니다.
  2. g_blk = G_block(20, strides=1, padding=0): G_block 클래스를 사용하여 생성자 네트워크의 블록을 하나 생성합니다. 이 블록은 스트라이드(strides)를 1로, 패딩(padding)을 0으로 설정하여 생성됩니다. 이렇게 설정하면 출력 이미지의 크기가 입력 이미지와 동일하게 유지됩니다. 출력 채널의 수는 20으로 설정됩니다.
  3. g_blk(x).shape: 생성자 블록 g_blk에 입력 데이터 x를 전달하여 가짜 이미지를 생성합니다. 그리고 생성된 가짜 이미지의 크기(shape)를 확인합니다.

이번 예시에서는 스트라이드와 패딩을 1과 0으로 설정하여 출력 이미지의 크기가 입력 이미지와 동일하게 유지되었습니다. 따라서 출력 이미지의 크기는 여전히 1x1입니다. 이렇게 설정하면 이미지의 공간 해상도가 유지되면서 채널 수가 늘어나는 효과가 있습니다. 스트라이드와 패딩을 조절하여 생성자 네트워크의 출력 이미지 크기를 조절할 수 있습니다.

torch.Size([2, 20, 4, 4])

The generator consists of four basic blocks that increase input’s both width and height from 1 to 32. At the same time, it first projects the latent variable into 64×8 channels, and then halve the channels each time. At last, a transposed convolution layer is used to generate the output. It further doubles the width and height to match the desired 64×64 shape, and reduces the channel size to 3. The tanh activation function is applied to project output values into the (−1,1) range.

 

생성기는 입력의 너비와 높이를 1에서 32로 증가시키는 4개의 기본 블록으로 구성됩니다. 동시에 잠재 변수를 먼저 64×8 채널로 투영한 다음 매번 채널을 절반으로 줄입니다. 마지막으로, 전치된 컨볼루션 레이어가 출력을 생성하는 데 사용됩니다. 원하는 64×64 모양과 일치하도록 너비와 높이를 추가로 두 배로 늘리고 채널 크기를 3으로 줄입니다. tanh 활성화 함수는 출력 값을 (-1,1) 범위로 투영하는 데 적용됩니다.

 

n_G = 64
net_G = nn.Sequential(
    G_block(in_channels=100, out_channels=n_G*8,
            strides=1, padding=0),                  # Output: (64 * 8, 4, 4)
    G_block(in_channels=n_G*8, out_channels=n_G*4), # Output: (64 * 4, 8, 8)
    G_block(in_channels=n_G*4, out_channels=n_G*2), # Output: (64 * 2, 16, 16)
    G_block(in_channels=n_G*2, out_channels=n_G),   # Output: (64, 32, 32)
    nn.ConvTranspose2d(in_channels=n_G, out_channels=3,
                       kernel_size=4, stride=2, padding=1, bias=False),
    nn.Tanh())  # Output: (3, 64, 64)

생성자 네트워크인 net_G를 정의하는 부분으로, GAN (Generative Adversarial Network) 모델에서 사용됩니다. 이 코드는 생성자 네트워크를 구성하고 각 블록의 출력 크기를 주석으로 설명하고 있습니다.

  1. n_G = 64: n_G는 생성자 네트워크에서 사용할 초기 채널 수를 나타냅니다. 이 값은 64로 설정되었습니다.
  2. net_G = nn.Sequential(...): 생성자 네트워크를 정의하는 nn.Sequential 컨테이너를 생성합니다. 이 컨테이너는 여러 레이어를 순차적으로 쌓을 수 있도록 합니다.
  3. G_block(...) 블록들: 생성자 네트워크는 G_block 클래스를 사용하여 여러 개의 블록으로 구성됩니다. 각 블록은 생성자 네트워크의 한 단계를 나타내며, 입력 데이터의 차원을 높이거나 채널 수를 줄이는 역할을 합니다. 주석으로 출력 크기를 표시했습니다. 예를 들어, 첫 번째 블록은 100차원의 랜덤 노이즈 벡터를 입력으로 받고, 출력으로 (64 * 8, 4, 4) 크기의 텐서를 생성합니다.
  4. nn.ConvTranspose2d(...) 레이어: 마지막에는 nn.ConvTranspose2d 레이어를 사용하여 최종 출력 이미지를 생성합니다. 이 레이어는 입력 이미지의 크기를 확대하고, 출력 채널 수를 3으로 설정하여 컬러 이미지를 생성합니다.
  5. nn.Tanh(): 마지막으로, Tanh 활성화 함수를 사용하여 출력 이미지의 픽셀 값을 [-1, 1] 범위로 조정합니다.

이렇게 정의된 net_G는 생성자 네트워크를 나타내며, 랜덤 노이즈 벡터로부터 실제 이미지와 유사한 가짜 이미지를 생성하는 역할을 합니다.

 

 

Generate a 100 dimensional latent variable to verify the generator’s output shape.

 

생성기의 출력 형태를 검증하기 위해 100차원 잠재변수를 생성합니다.

 

x = torch.zeros((1, 100, 1, 1))
net_G(x).shape

생성자 네트워크인 net_G에 랜덤 노이즈 벡터를 입력으로 주고, 이를 이용하여 가짜 이미지를 생성한 후, 생성된 이미지의 크기(shape)를 확인하는 예시를 보여줍니다.

  1. x = torch.zeros((1, 100, 1, 1)): 크기가 (1, 100, 1, 1)인 4D 텐서를 생성합니다. 이 텐서는 생성자 네트워크 net_G의 입력으로 사용될 랜덤 노이즈 벡터를 나타냅니다. 이 랜덤 노이즈 벡터는 100차원이며, 크기가 1x1인 가짜 이미지를 생성하기 위한 초기 입력으로 사용됩니다.
  2. net_G(x).shape: 생성자 네트워크 net_G에 랜덤 노이즈 벡터 x를 전달하여 가짜 이미지를 생성합니다. 그리고 생성된 가짜 이미지의 크기(shape)를 확인합니다.

코드를 실행하면 랜덤 노이즈 벡터를 입력으로 사용하여 생성자 네트워크가 가짜 이미지를 생성하고, 이 이미지의 크기(shape)를 확인합니다. 실제로 실행할 때마다 다른 랜덤한 이미지가 생성됩니다. 이것은 GAN 모델에서 생성자의 역할로 사용되며, 생성자는 학습을 통해 실제 이미지와 유사한 가짜 이미지를 생성하는 능력을 향상시킵니다.

 

torch.Size([1, 3, 64, 64])

 

20.2.3. Discriminator

The discriminator is a normal convolutional network network except that it uses a leaky ReLU as its activation function. Given α∈[0,1], its definition is

 

판별자는 활성화 함수로 Leaky ReLU를 사용한다는 점을 제외하면 일반적인 컨벌루션 네트워크 네트워크입니다. α∈[0,1]이 주어지면 그 정의는 다음과 같습니다.

 

As it can be seen, it is normal ReLU if α=0, and an identity function if α=1. For α∈(0,1), leaky ReLU is a nonlinear function that give a non-zero output for a negative input. It aims to fix the “dying ReLU” problem that a neuron might always output a negative value and therefore cannot make any progress since the gradient of ReLU is 0.

 

보시다시피, α=0이면 일반 ReLU이고, α=1이면 항등함수입니다. α∈(0,1)의 경우 Leaky ReLU는 음수 입력에 대해 0이 아닌 출력을 제공하는 비선형 함수입니다. 뉴런이 항상 음수 값을 출력할 수 있고 ReLU의 기울기가 0이기 때문에 어떤 진전도 할 수 없는 "죽어가는 ReLU" 문제를 해결하는 것이 목표입니다.

 

alphas = [0, .2, .4, .6, .8, 1]
x = torch.arange(-2, 1, 0.1)
Y = [nn.LeakyReLU(alpha)(x).detach().numpy() for alpha in alphas]
d2l.plot(x.detach().numpy(), Y, 'x', 'y', alphas)

다양한 Leaky ReLU 활성화 함수에서의 출력을 시각화하는 예시를 보여줍니다.

  1. alphas = [0, .2, .4, .6, .8, 1]: Leaky ReLU 활성화 함수에 사용될 alpha 값을 리스트로 정의합니다. alpha 값은 Leaky ReLU 함수에서 음수 입력에 대한 출력의 기울기를 나타냅니다. 여기서는 다양한 alpha 값을 실험해보고 시각화합니다.
  2. x = torch.arange(-2, 1, 0.1): -2부터 1까지 0.1 간격으로 숫자를 생성하여 x에 저장합니다. 이 범위의 숫자는 Leaky ReLU 함수에 입력으로 사용됩니다.
  3. Y = [nn.LeakyReLU(alpha)(x).detach().numpy() for alpha in alphas]: 각 alpha 값에 대해 Leaky ReLU 활성화 함수를 x에 적용하고 결과를 Y 리스트에 저장합니다. detach().numpy()를 사용하여 PyTorch 텐서를 넘파이 배열로 변환합니다.
  4. d2l.plot(x.detach().numpy(), Y, 'x', 'y', alphas): d2l.plot 함수를 사용하여 결과를 시각화합니다. x 축은 입력 x의 값, y 축은 Leaky ReLU 함수의 출력 값입니다. 각 alpha 값에 해당하는 곡선이 다른 색상으로 표시됩니다. 이를 통해 Leaky ReLU 활성화 함수의 alpha 값이 변할 때 어떻게 출력이 달라지는지를 시각적으로 확인할 수 있습니다.

코드를 실행하면 다양한 alpha 값에 대한 Leaky ReLU 함수의 출력을 시각화한 그래프가 표시됩니다. alpha 값이 커질수록 입력의 음수 부분에 대한 출력이 크게 유지되는 것을 관찰할 수 있습니다. 이를 통해 Leaky ReLU의 역할을 이해할 수 있습니다.

 

The basic block of the discriminator is a convolution layer followed by a batch normalization layer and a leaky ReLU activation. The hyperparameters of the convolution layer are similar to the transpose convolution layer in the generator block.

 

판별기의 기본 블록은 컨볼루션 계층과 그 뒤에 배치 정규화 계층 및 누출된 ReLU 활성화로 구성됩니다. 컨볼루션 레이어의 하이퍼파라미터는 생성기 블록의 전치 컨볼루션 레이어와 유사합니다.

 

class D_block(nn.Module):
    def __init__(self, out_channels, in_channels=3, kernel_size=4, strides=2,
                padding=1, alpha=0.2, **kwargs):
        super(D_block, self).__init__(**kwargs)
        self.conv2d = nn.Conv2d(in_channels, out_channels, kernel_size,
                                strides, padding, bias=False)
        self.batch_norm = nn.BatchNorm2d(out_channels)
        self.activation = nn.LeakyReLU(alpha, inplace=True)

    def forward(self, X):
        return self.activation(self.batch_norm(self.conv2d(X)))

 

이 코드는 GAN (Generative Adversarial Network)의 판별자 네트워크를 정의하는 클래스 D_block을 생성하는 파이토치(PyTorch) 코드입니다.

 

이 클래스는 판별자 네트워크의 블록을 정의합니다. 여기서 각 요소의 역할은 다음과 같습니다:

  • out_channels: 이 블록에서 생성될 출력 채널의 수를 나타냅니다.
  • in_channels: 입력 데이터의 채널 수를 나타냅니다. 기본값은 3으로, 이는 RGB 이미지를 가정합니다.
  • kernel_size: 컨볼루션 커널의 크기를 나타냅니다. 기본값은 4로, 4x4 크기의 커널을 사용합니다.
  • strides: 컨볼루션 연산에서 스트라이드를 나타냅니다. 기본값은 2로, 스트라이드 2로 컨볼루션을 수행합니다.
  • padding: 컨볼루션 연산에서 패딩을 나타냅니다. 기본값은 1로, 1 픽셀의 패딩을 적용합니다.
  • alpha: Leaky ReLU 활성화 함수에서 사용되는 negative slope 값을 나타냅니다. 기본값은 0.2로, 일반적으로 사용되는 값입니다.

이 클래스의 forward 메서드에서는 다음과 같은 작업을 수행합니다:

  1. self.conv2d(X): 입력 데이터 X에 대해 컨볼루션 연산을 수행합니다. 이 연산은 채널 수와 커널 크기에 따라 출력 텐서를 생성합니다.
  2. self.batch_norm(...): 컨볼루션 연산의 결과에 배치 정규화를 적용합니다. 이는 네트워크의 안정성과 학습 속도를 향상시키는 데 도움을 줍니다.
  3. self.activation(...): 배치 정규화를 거친 결과에 Leaky ReLU 활성화 함수를 적용합니다. Leaky ReLU는 양수 값은 그대로 두고 음수 값에 작은 기울기를 적용하는 함수로, GAN에서 주로 사용됩니다.

이 클래스를 사용하면 판별자 네트워크에서 한 블록을 구성하고, 여러 개의 이러한 블록을 조합하여 전체 판별자 네트워크를 구축할 수 있습니다. 이러한 블록을 사용하여 이미지의 특징을 추출하고 진짜와 가짜 이미지를 구분하는 역할을 수행합니다.

 

A basic block with default settings will halve the width and height of the inputs, as we demonstrated in Section 7.3. For example, given a input shape nℎ=nw=16, with a kernel shape kℎ=kw=4, a stride shape sℎ=sw=2, and a padding shape pℎ=pw=1, the output shape will be:

 

섹션 7.3에서 설명한 것처럼 기본 설정이 있는 기본 블록은 입력의 너비와 높이를 절반으로 줄입니다. 예를 들어 입력 형태 nℎ=nw=16, 커널 형태 kℎ=kw=4, 스트라이드 형태 sℎ=sw=2, 패딩 형태 pℎ=pw=1이 있는 경우 출력 형태는 다음과 같습니다.

 

x = torch.zeros((2, 3, 16, 16))
d_blk = D_block(20)
d_blk(x).shape

판별자 네트워크의 D_block 클래스를 사용하여 가짜 이미지에 대한 판별 결과를 계산하는 예시를 보여줍니다.

  1. x = torch.zeros((2, 3, 16, 16)): 2개의 샘플(batch size가 2), 3개의 채널(channel), 각각 16x16 크기의 이미지를 나타내는 4D 텐서를 생성합니다. 이 텐서는 판별자 네트워크 d_blk에 대한 입력 데이터로 사용됩니다.
  2. d_blk = D_block(20): D_block 클래스를 사용하여 판별자 네트워크의 블록을 하나 생성합니다. 이 블록은 3D 텐서를 입력으로 받아 처리하고, 출력으로 판별 결과를 나타내는 텐서를 생성합니다. 여기서 out_channels를 20으로 설정하여 출력 채널의 수를 20으로 정의합니다.
  3. d_blk(x).shape: 판별자 블록 d_blk에 입력 데이터 x를 전달하여 가짜 이미지에 대한 판별 결과를 계산합니다. 그리고 판별 결과의 크기(shape)를 확인합니다.

코드를 실행하면 가짜 이미지에 대한 판별 결과가 계산되고, 이 결과의 크기(shape)가 반환됩니다. 판별자 네트워크는 입력 이미지에 대한 판별 결과를 출력하며, 이를 통해 가짜 이미지와 실제 이미지를 구별합니다.

torch.Size([2, 20, 8, 8])

 

A basic block with default settings will halve the width and height of the inputs, as we demonstrated in Section 7.3. For example, given a input shape nℎ=nw=16, with a kernel shape kℎ=kw=4, a stride shape sℎ=sw=2, and a padding shape pℎ=pw=1, the output shape will be:

 

섹션 7.3에서 설명한 것처럼 기본 설정이 있는 기본 블록은 입력의 너비와 높이를 절반으로 줄입니다. 예를 들어 입력 형태 nℎ=nw=16, 커널 형태 kℎ=kw=4, 스트라이드 형태 sℎ=sw=2, 패딩 형태 pℎ=pw=1이 있는 경우 출력 형태는 다음과 같습니다.

 

 

x = torch.zeros((2, 3, 16, 16))
d_blk = D_block(20)
d_blk(x).shape

판별자 네트워크의 D_block 클래스를 사용하여 가짜 이미지에 대한 판별 결과를 계산하는 예시를 보여줍니다.

  1. x = torch.zeros((2, 3, 16, 16)): 2개의 샘플(batch size가 2), 3개의 채널(channel), 각각 16x16 크기의 이미지를 나타내는 4D 텐서를 생성합니다. 이 텐서는 판별자 네트워크 d_blk에 대한 입력 데이터로 사용됩니다.
  2. d_blk = D_block(20): D_block 클래스를 사용하여 판별자 네트워크의 블록을 하나 생성합니다. 이 블록은 3D 텐서를 입력으로 받아 처리하고, 출력으로 판별 결과를 나타내는 텐서를 생성합니다. 여기서 out_channels를 20으로 설정하여 출력 채널의 수를 20으로 정의합니다.
  3. d_blk(x).shape: 판별자 블록 d_blk에 입력 데이터 x를 전달하여 가짜 이미지에 대한 판별 결과를 계산합니다. 그리고 판별 결과의 크기(shape)를 확인합니다.

코드를 실행하면 가짜 이미지에 대한 판별 결과가 계산되고, 이 결과의 크기(shape)가 반환됩니다. 판별자 네트워크는 입력 이미지에 대한 판별 결과를 출력하며, 이를 통해 가짜 이미지와 실제 이미지를 구별합니다. 이 코드는 판별자 블록이 입력 이미지를 어떻게 처리하고 판별 결과를 출력하는지를 보여주는 예시입니다.

torch.Size([2, 20, 8, 8])

 

The discriminator is a mirror of the generator.

 

판별자는 생성자의 거울입니다.

 

n_D = 64
net_D = nn.Sequential(
    D_block(n_D),  # Output: (64, 32, 32)
    D_block(in_channels=n_D, out_channels=n_D*2),  # Output: (64 * 2, 16, 16)
    D_block(in_channels=n_D*2, out_channels=n_D*4),  # Output: (64 * 4, 8, 8)
    D_block(in_channels=n_D*4, out_channels=n_D*8),  # Output: (64 * 8, 4, 4)
    nn.Conv2d(in_channels=n_D*8, out_channels=1,
              kernel_size=4, bias=False))  # Output: (1, 1, 1)

판별자 네트워크인 net_D를 정의하는 부분으로, GAN (Generative Adversarial Network) 모델에서 사용됩니다. 이 코드는 판별자 네트워크를 구성하고 각 블록의 출력 크기를 주석으로 설명하고 있습니다.

  1. n_D = 64: n_D는 판별자 네트워크에서 사용할 초기 채널 수를 나타냅니다. 이 값은 64로 설정되었습니다.
  2. net_D = nn.Sequential(...): 판별자 네트워크를 정의하는 nn.Sequential 컨테이너를 생성합니다. 이 컨테이너는 여러 레이어를 순차적으로 쌓을 수 있도록 합니다.
  3. D_block(...) 블록들: 판별자 네트워크는 D_block 클래스를 사용하여 여러 개의 블록으로 구성됩니다. 각 블록은 판별자 네트워크의 한 단계를 나타내며, 입력 데이터의 차원을 줄이거나 채널 수를 늘리는 역할을 합니다. 주석으로 출력 크기를 표시했습니다. 예를 들어, 첫 번째 블록은 (64, 32, 32) 크기의 텐서를 입력으로 받고, 출력으로 (64, 32, 32) 크기의 텐서를 생성합니다.
  4. nn.Conv2d(...) 레이어: 마지막에는 nn.Conv2d 레이어를 사용하여 최종 판별 결과를 생성합니다. 이 레이어는 입력 이미지를 판별한 결과를 출력하며, 출력 채널 수는 1로 설정되어 이진 분류 결과를 나타냅니다.

이렇게 정의된 net_D는 판별자 네트워크를 나타내며, 입력 이미지를 판별하여 이미지가 진짜인지 가짜인지를 판별하는 역할을 합니다. 판별자 네트워크는 이미지의 공간적 정보를 이용하여 판별 결과를 계산합니다.

 

 

It uses a convolution layer with output channel 1 as the last layer to obtain a single prediction value.

 

단일 예측 값을 얻기 위해 출력 채널 1이 있는 컨볼루션 레이어를 마지막 레이어로 사용합니다.

 

x = torch.zeros((1, 3, 64, 64))
net_D(x).shape

판별자 네트워크인 net_D에 입력 데이터를 전달하고, 판별 결과의 크기(shape)를 확인하는 예시를 보여줍니다.

  1. x = torch.zeros((1, 3, 64, 64)): 크기가 (1, 3, 64, 64)인 4D 텐서를 생성합니다. 이 텐서는 판별자 네트워크 net_D에 입력 데이터로 사용됩니다. 여기서 크기 (1, 3, 64, 64)은 배치 크기가 1이고, 채널 수가 3 (RGB 이미지)이며, 이미지 크기가 64x64임을 의미합니다.
  2. net_D(x).shape: 생성된 입력 데이터 x를 판별자 네트워크 net_D에 전달하여 판별 결과를 계산합니다. 그리고 판별 결과의 크기(shape)를 확인합니다.

코드를 실행하면 판별자 네트워크가 입력 이미지 x를 판별하고, 판별 결과의 크기(shape)가 반환됩니다. 판별자는 입력 이미지를 받아 이미지가 진짜인지 가짜인지 판별하는 역할을 수행합니다. 이 코드는 판별자 네트워크의 출력을 확인하는 간단한 예시입니다.

torch.Size([1, 1, 1, 1])

 

20.2.4. Training

Compared to the basic GAN in Section 20.1, we use the same learning rate for both generator and discriminator since they are similar to each other. In addition, we change β1 in Adam (Section 12.10) from 0.9 to 0.5. It decreases the smoothness of the momentum, the exponentially weighted moving average of past gradients, to take care of the rapid changing gradients because the generator and the discriminator fight with each other. Besides, the random generated noise Z, is a 4-D tensor and we are using GPU to accelerate the computation.

 

20.1절의 기본 GAN과 비교하면 생성자와 판별자가 서로 유사하므로 동일한 학습률을 사용합니다. 또한 Adam(12.10절)의 β1을 0.9에서 0.5로 변경합니다. 생성자와 판별자가 서로 싸우기 때문에 빠르게 변화하는 기울기를 처리하기 위해 과거 기울기의 지수 가중 이동 평균인 운동량의 평활도를 감소시킵니다. 게다가 무작위로 생성된 노이즈 Z는 4차원 텐서이며 GPU를 사용하여 계산을 가속화합니다.

 

def train(net_D, net_G, data_iter, num_epochs, lr, latent_dim,
          device=d2l.try_gpu()):
    loss = nn.BCEWithLogitsLoss(reduction='sum')
    for w in net_D.parameters():
        nn.init.normal_(w, 0, 0.02)
    for w in net_G.parameters():
        nn.init.normal_(w, 0, 0.02)
    net_D, net_G = net_D.to(device), net_G.to(device)
    trainer_hp = {'lr': lr, 'betas': [0.5,0.999]}
    trainer_D = torch.optim.Adam(net_D.parameters(), **trainer_hp)
    trainer_G = torch.optim.Adam(net_G.parameters(), **trainer_hp)
    animator = d2l.Animator(xlabel='epoch', ylabel='loss',
                            xlim=[1, num_epochs], nrows=2, figsize=(5, 5),
                            legend=['discriminator', 'generator'])
    animator.fig.subplots_adjust(hspace=0.3)
    for epoch in range(1, num_epochs + 1):
        # Train one epoch
        timer = d2l.Timer()
        metric = d2l.Accumulator(3)  # loss_D, loss_G, num_examples
        for X, _ in data_iter:
            batch_size = X.shape[0]
            Z = torch.normal(0, 1, size=(batch_size, latent_dim, 1, 1))
            X, Z = X.to(device), Z.to(device)
            metric.add(d2l.update_D(X, Z, net_D, net_G, loss, trainer_D),
                       d2l.update_G(Z, net_D, net_G, loss, trainer_G),
                       batch_size)
        # Show generated examples
        Z = torch.normal(0, 1, size=(21, latent_dim, 1, 1), device=device)
        # Normalize the synthetic data to N(0, 1)
        fake_x = net_G(Z).permute(0, 2, 3, 1) / 2 + 0.5
        imgs = torch.cat(
            [torch.cat([
                fake_x[i * 7 + j].cpu().detach() for j in range(7)], dim=1)
             for i in range(len(fake_x)//7)], dim=0)
        animator.axes[1].cla()
        animator.axes[1].imshow(imgs)
        # Show the losses
        loss_D, loss_G = metric[0] / metric[2], metric[1] / metric[2]
        animator.add(epoch, (loss_D, loss_G))
    print(f'loss_D {loss_D:.3f}, loss_G {loss_G:.3f}, '
          f'{metric[2] / timer.stop():.1f} examples/sec on {str(device)}')

GAN (Generative Adversarial Network) 모델의 학습 함수를 정의하고 있습니다. 이 함수는 판별자와 생성자 네트워크를 학습하는 역할을 합니다.

  1. net_D와 net_G: 판별자 네트워크와 생성자 네트워크를 나타내는 모델 객체입니다.
  2. data_iter: 데이터 로더로부터 생성된 데이터 배치를 나타내는 반복자입니다.
  3. num_epochs: 학습할 epoch 수입니다.
  4. lr: 학습률 (learning rate)입니다.
  5. latent_dim: 생성자 네트워크의 입력 랜덤 벡터의 차원입니다.
  6. device: 모델을 학습할 디바이스 (CPU 또는 GPU)를 나타냅니다.
  7. loss = nn.BCEWithLogitsLoss(reduction='sum'): 이진 교차 엔트로피 손실 함수를 정의합니다. GAN에서는 이 손실 함수를 사용하여 판별자의 출력과 진짜/가짜 레이블 사이의 오차를 계산합니다.
  8. 모델 가중치 초기화: 생성자와 판별자 네트워크의 가중치를 초기화합니다.
  9. trainer_D와 trainer_G: 판별자와 생성자 네트워크를 각각 최적화하기 위한 Adam 옵티마이저를 생성합니다.
  10. animator: 학습 과정을 시각화하기 위한 d2l.Animator 객체를 생성합니다.
  11. 학습 루프: 지정된 epoch 수만큼 학습을 수행합니다. 각 epoch에서는 판별자와 생성자를 번갈아가며 학습하고, 학습 중간에 생성된 이미지를 시각화하여 학습 진행 상황을 확인합니다.
  12. 학습 속도 계산: 학습이 완료된 후, 판별자와 생성자의 손실과 학습 속도를 출력합니다.

이 함수는 GAN 모델을 학습하기 위한 핵심 학습 루프를 구현하고 있으며, 판별자와 생성자 네트워크의 학습을 번갈아가며 진행합니다. 학습이 진행됨에 따라 손실이 어떻게 변하는지 시각화하고, 학습 속도도 출력하여 모델의 학습 상태를 모니터링합니다.

 

We train the model with a small number of epochs just for demonstration. For better performance, the variable num_epochs can be set to a larger number.

 

단지 시연을 위해 적은 수의 에포크로 모델을 훈련합니다. 더 나은 성능을 위해 num_epochs 변수를 더 큰 숫자로 설정할 수 있습니다.

 

latent_dim, lr, num_epochs = 100, 0.005, 20
train(net_D, net_G, data_iter, num_epochs, lr, latent_dim)

GAN 모델을 학습하기 위해 앞서 정의한 train 함수를 호출하는 부분입니다.

  1. latent_dim: 생성자 네트워크의 입력 랜덤 벡터의 차원을 나타냅니다. 여기서는 100으로 설정되었습니다.
  2. lr: 학습률 (learning rate)을 나타냅니다. 학습률은 0.005로 설정되었습니다.
  3. num_epochs: 학습할 epoch 수를 나타냅니다. 여기서는 20으로 설정되었습니다.
  4. train(net_D, net_G, data_iter, num_epochs, lr, latent_dim): 이전에 정의한 train 함수를 호출하여 GAN 모델을 학습합니다. 학습에 필요한 인자들을 함수에 전달합니다. 이렇게 하면 판별자와 생성자 네트워크가 데이터로부터 학습을 수행하고, 지정된 epoch 수만큼 학습이 진행됩니다.

이 코드는 GAN 모델을 실제 데이터로부터 학습시키는 부분을 실행하는 부분입니다. latent_dim, lr, num_epochs 등의 하이퍼파라미터를 설정하고, train 함수를 호출하여 학습을 시작합니다.

loss_D 0.023, loss_G 7.359, 2292.7 examples/sec on cuda:0

 

 

두번째 실행 결과

epochs를 50으로 했을 때

 

20.2.5. Summary

  • DCGAN architecture has four convolutional layers for the Discriminator and four “fractionally-strided” convolutional layers for the Generator.

    DCGAN 아키텍처에는 판별자(Discriminator)용 컨벌루션 레이어 4개와 생성기(Generator)용 "부분 스트라이드" 컨벌루션 레이어 4개가 있습니다.

  • The Discriminator is a 4-layer strided convolutions with batch normalization (except its input layer) and leaky ReLU activations.

    Discriminator는 배치 정규화(입력 레이어 제외) 및 Leaky ReLU 활성화 기능을 갖춘 4레이어 스트라이드 컨볼루션입니다.

  • Leaky ReLU is a nonlinear function that give a non-zero output for a negative input. It aims to fix the “dying ReLU” problem and helps the gradients flow easier through the architecture.

    Leaky ReLU는 음수 입력에 대해 0이 아닌 출력을 제공하는 비선형 함수입니다. 이는 "죽어가는 ReLU" 문제를 해결하는 것을 목표로 하며 아키텍처를 통해 그래디언트가 더 쉽게 흐르도록 돕습니다.

20.2.6. Exercises

  1. What will happen if we use standard ReLU activation rather than leaky ReLU?
  2. Apply DCGAN on Fashion-MNIST and see which category works well and which does not.

 

 

 

 

 

 

 

 

 

반응형


반응형

20.1. Generative Adversarial Networks — Dive into Deep Learning 1.0.3 documentation (d2l.ai)

 

20.1. Generative Adversarial Networks — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

20.1. Generative Adversarial Networks

Throughout most of this book, we have talked about how to make predictions. In some form or another, we used deep neural networks to learn mappings from data examples to labels. This kind of learning is called discriminative learning, as in, we’d like to be able to discriminate between photos of cats and photos of dogs. Classifiers and regressors are both examples of discriminative learning. And neural networks trained by backpropagation have upended everything we thought we knew about discriminative learning on large complicated datasets. Classification accuracies on high-res images have gone from useless to human-level (with some caveats) in just 5-6 years. We will spare you another spiel about all the other discriminative tasks where deep neural networks do astoundingly well.

 

이 책의 대부분에서 우리는 예측하는 방법에 대해 이야기했습니다. 어떤 형태로든 우리는 심층 신경망을 사용하여 데이터 예제에서 레이블까지의 매핑을 학습했습니다. 이런 종류의 학습을 차별적 학습 discriminative learning 이라고 합니다. 고양이 사진과 개 사진을 구별할 수 있기를 원하기 때문입니다. 분류기 Classifiers 와 회귀자 regressors 는 모두 차별 학습 discriminative learning 의 예입니다. 그리고 역전파로 훈련된 신경망은 크고 복잡한 데이터 세트에 대한 차별적 학습에 대해 우리가 알고 있다고 생각했던 모든 것을 뒤집어 놓았습니다. 고해상도 이미지의 분류 정확도는 단 5~6년 만에 쓸모없는 수준에서 인간 수준(몇 가지 주의 사항 있음)으로 바뀌었습니다. 심층 신경망이 놀라울 정도로 잘 수행되는 다른 모든 식별 작업에 대해 더 이상 이야기하지 않겠습니다.

 

But there is more to machine learning than just solving discriminative tasks. For example, given a large dataset, without any labels, we might want to learn a model that concisely captures the characteristics of this data. Given such a model, we could sample synthetic data examples that resemble the distribution of the training data. For example, given a large corpus of photographs of faces, we might want to be able to generate a new photorealistic image that looks like it might plausibly have come from the same dataset. This kind of learning is called generative modeling.

 

그러나 머신러닝에는 단지 차별적 discriminative 인 작업을 해결하는 것보다 더 많은 것이 있습니다. 예를 들어, 라벨이 없는 대규모 데이터 세트가 있으면 이 데이터의 특성을 간결하게 포착하는 모델을 학습하고 싶을 수 있습니다. 이러한 모델이 주어지면 훈련 데이터의 분포와 유사한 합성 데이터 예제를 샘플링할 수 있습니다. 예를 들어, 얼굴 사진으로 구성된 대규모 코퍼스가 있으면 동일한 데이터세트에서 나온 것처럼 보이는 새로운 사실적인 이미지를 생성할 수 있기를 원할 수 있습니다. 이러한 종류의 학습을 생성 모델링이라고 합니다.

 

Until recently, we had no method that could synthesize novel photorealistic images. But the success of deep neural networks for discriminative learning opened up new possibilities. One big trend over the last three years has been the application of discriminative deep nets to overcome challenges in problems that we do not generally think of as supervised learning problems. The recurrent neural network language models are one example of using a discriminative network (trained to predict the next character) that once trained can act as a generative model.

 

최근까지 우리는 새로운 사실적 이미지를 합성할 수 있는 방법이 없었습니다. 그러나 차별적 학습을 위한 심층 신경망의 성공은 새로운 가능성을 열어주었습니다. 지난 3년 동안의 큰 추세 중 하나는 일반적으로 지도 학습 문제로 생각하지 않는 문제를 극복하기 위해 차별적인 딥 넷을 적용한 것입니다. 순환 신경망 언어 모델은 일단 훈련되면 생성 모델 역할을 할 수 있는 식별 네트워크(다음 문자를 예측하도록 훈련됨)를 사용하는 한 가지 예입니다.

 

In 2014, a breakthrough paper introduced Generative adversarial networks (GANs) (Goodfellow et al., 2014), a clever new way to leverage the power of discriminative models to get good generative models. At their heart, GANs rely on the idea that a data generator is good if we cannot tell fake data apart from real data. In statistics, this is called a two-sample test - a test to answer the question whether datasets X={x1,…,xn} and X′={x1′,…,x'n} were drawn from the same distribution. The main difference between most statistics papers and GANs is that the latter use this idea in a constructive way. In other words, rather than just training a model to say “hey, these two datasets do not look like they came from the same distribution”, they use the two-sample test to provide training signals to a generative model. This allows us to improve the data generator until it generates something that resembles the real data. At the very least, it needs to fool the classifier even if our classifier is a state of the art deep neural network.

 

2014년 획기적인 논문에서는 판별 모델의 힘을 활용하여 좋은 생성 모델을 얻는 영리하고 새로운 방법인 생성적 적대 네트워크(GAN)(Goodfellow et al., 2014)를 소개했습니다. GAN의 핵심은 실제 데이터와 가짜 데이터를 구별할 수 없다면 데이터 생성기가 좋다는 생각에 의존합니다. 통계에서는 이를 2-표본 검정이라고 합니다. 즉, 데이터 세트 X={x1,…,xn} 및 X′={x1′,…,x'n}이 동일한 분포에서 추출되었는지 여부에 대한 질문에 대답하는 테스트입니다. 대부분의 통계 논문과 GAN의 주요 차이점은 후자가 이 아이디어를 건설적인 방식으로 사용한다는 것입니다. 즉, 단순히 "이 두 데이터 세트는 동일한 분포에서 나온 것처럼 보이지 않습니다"라고 말하도록 모델을 훈련시키는 대신 2-샘플 테스트를 사용하여 생성 모델에 훈련 신호를 제공합니다. 이를 통해 실제 데이터와 유사한 것을 생성할 때까지 데이터 생성기를 개선할 수 있습니다. 최소한 분류기가 최첨단 심층 신경망이라 하더라도 분류기를 속일 필요는 있습니다.

 

Fig. 20.1.1  Generative Adversarial Networks

The GAN architecture is illustrated in Fig. 20.1.1. As you can see, there are two pieces in GAN architecture - first off, we need a device (say, a deep network but it really could be anything, such as a game rendering engine) that might potentially be able to generate data that looks just like the real thing. If we are dealing with images, this needs to generate images. If we are dealing with speech, it needs to generate audio sequences, and so on. We call this the generator network. The second component is the discriminator network. It attempts to distinguish fake and real data from each other. Both networks are in competition with each other. The generator network attempts to fool the discriminator network. At that point, the discriminator network adapts to the new fake data. This information, in turn is used to improve the generator network, and so on.

 

GAN 아키텍처는 그림 20.1.1에 설명되어 있습니다. 보시다시피, GAN 아키텍처에는 두 가지 부분이 있습니다. 먼저, 잠재적으로 보이는 데이터를 생성할 수 있는 장치(예: 심층 네트워크이지만 실제로는 게임 렌더링 엔진과 같은 모든 것이 될 수 있음)가 필요합니다. 진짜처럼. 이미지를 다루는 경우 이미지를 생성해야 합니다. 음성을 다루는 경우 오디오 시퀀스 등을 생성해야 합니다. 우리는 이것을 Generator 네트워크라고 부릅니다. 두 번째 구성 요소는 discriminator 네트워크입니다. 가짜 데이터와 실제 데이터를 구별하려고 시도합니다. 두 네트워크는 서로 경쟁하고 있습니다. 생성자 네트워크는 판별자 discriminator  네트워크를 속이려고 시도합니다. 이 시점에서 판별기 네트워크는 새로운 가짜 데이터에 적응합니다. 이 정보는 generator network 등을 개선하는 데 사용됩니다.

 

The discriminator is a binary classifier to distinguish if the input x is real (from real data) or fake (from the generator). Typically, the discriminator outputs a scalar prediction o∈ for input x, such as using a fully connected layer with hidden size 1, and then applies sigmoid function to obtain the predicted probability D(x)=1/(1+e**−o). Assume the label y for the true data is 1 and 0 for the fake data. We train the discriminator to minimize the cross-entropy loss, i.e.,

 

판별자는 입력 x가 실제(실제 데이터에서)인지 가짜(생성기에서)인지 구별하는 이진 분류기입니다. 일반적으로 판별기는 은닉 크기가 1인 완전 연결 레이어를 사용하는 것과 같이 입력 x에 대해 스칼라 예측 o∈ℝ을 출력합니다. 그런 다음 시그모이드 함수를 적용하여 예측 확률 'D(x)=1/(1+e**−o)'를 얻습니다. 실제 데이터의 레이블 y는 1이고 가짜 데이터의 레이블은 0이라고 가정합니다. 교차 엔트로피 손실을 최소화하기 위해 판별자를 훈련합니다. 즉,

 

 

For the generator, it first draws some parameter z∈ℝ**d from a source of randomness, e.g., a normal distribution z∼N(0,1). We often call z as the latent variable. It then applies a function to generate x′=G(z). The goal of the generator is to fool the discriminator to classify x′=G(z) as true data, i.e., we want D(G(z))≈1. In other words, for a given discriminator D, we update the parameters of the generator G to maximize the cross-entropy loss when y=0, i.e.,

 

생성기의 경우 먼저 임의성의 소스(예: 정규 분포 z∼N(0,1))에서 일부 매개변수 z∈ℝ**d를 그립니다. 우리는 종종 z를 잠재 변수라고 부릅니다. 그런 다음 x′=G(z)를 생성하는 함수를 적용합니다. 생성기의 목표는 판별기를 속여 x′=G(z)를 실제 데이터로 분류하는 것입니다. 즉, D(G(z))≒1을 원합니다. 즉, 주어진 판별기 D에 대해 생성기 G의 매개변수를 업데이트하여 y=0일 때 교차 엔트로피 손실을 최대화합니다. 즉,

 

 

If the generator does a perfect job, then D(x′)≈1, so the above loss is near 0, which results in the gradients that are too small to make good progress for the discriminator. So commonly, we minimize the following loss:

 

생성기가 완벽한 작업을 수행하면 D(x′) ≒1이므로 위의 손실은 0에 가까워서 판별기가 제대로 진행하기에는 기울기가 너무 작아집니다. 따라서 일반적으로 다음 손실을 최소화합니다.

 

which is just feeding x′=G(z) into the discriminator but giving label y=1.

 

x′=G(z)를 판별자에 입력하지만 라벨 y=1을 제공합니다.

 

To sum up, D and G are playing a “minimax” game with the comprehensive objective function:

 

요약하자면, D와 G는 포괄적인 목적 함수를 사용하여 "미니맥스" 게임을 하고 있습니다.

 

Many of the GANs applications are in the context of images. As a demonstration purpose, we are going to content ourselves with fitting a much simpler distribution first. We will illustrate what happens if we use GANs to build the world’s most inefficient estimator of parameters for a Gaussian. Let’s get started.

 

GAN 애플리케이션의 대부분은 이미지와 관련되어 있습니다. 데모 목적으로 먼저 훨씬 간단한 배포판을 맞추는 것으로 만족하겠습니다. GAN을 사용하여 세계에서 가장 비효율적인 가우스 매개변수 추정기를 구축하면 어떤 일이 발생하는지 설명하겠습니다. 시작하자.

 

%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2l
  1. %matplotlib inline: 이 코드 라인은 주피터 노트북 환경에서 그래프를 인라인으로 표시하도록 지정하는 명령입니다. 즉, 그래프가 노트북 안에서 바로 표시됩니다.
  2. import torch: 파이토치 라이브러리를 임포트합니다. 파이토치는 딥 러닝 모델을 구축하고 학습하는 데 사용되는 라이브러리입니다.
  3. from torch import nn: 파이토치의 nn 모듈에서 필요한 부분을 가져옵니다. nn 모듈은 신경망을 정의하고 학습하는 데 사용되는 다양한 도구와 클래스를 포함하고 있습니다.
  4. from d2l import torch as d2l: "Dive into Deep Learning" 라이브러리에서 torch 모듈을 가져옵니다. 이 라이브러리는 교재와 관련된 유틸리티 함수와 도우미 함수를 제공합니다.

이 코드의 주요 목적은 파이토치와 "Dive into Deep Learning" 라이브러리를 설정하고 사용 가능한 도구와 기능을 가져오는 것입니다. 이러한 도구와 기능은 GAN을 구현하고 실험하는 데 사용될 것입니다.

 

20.1.1. Generate Some “Real” Data

Since this is going to be the world’s lamest example, we simply generate data drawn from a Gaussian.

 

이것은 세계에서 가장 형편없는 예가 될 것이기 때문에 우리는 단순히 가우스에서 가져온 데이터를 생성합니다.

 

X = torch.normal(0.0, 1, (1000, 2))
A = torch.tensor([[1, 2], [-0.1, 0.5]])
b = torch.tensor([1, 2])
data = torch.matmul(X, A) + b
  1. X = torch.normal(0.0, 1, (1000, 2)): X는 평균이 0이고 표준 편차가 1인 정규 분포 (표준 정규 분포)에서 무작위로 샘플링된 값을 가지는 1000x2 크기의 텐서입니다. 이는 평균이 0이고 표준 편차가 1인 가우시안 분포에서 무작위로 데이터를 생성하는 것을 나타냅니다.
  2. A = torch.tensor([[1, 2], [-0.1, 0.5]]): A는 2x2 크기의 텐서로, 행렬입니다. 이 행렬은 데이터에 곱해져서 변환을 수행하는 데 사용될 것입니다. 첫 번째 행은 [1, 2]이고 두 번째 행은 [-0.1, 0.5]입니다.
  3. b = torch.tensor([1, 2]): b는 1x2 크기의 텐서로, 벡터입니다. 이 벡터는 데이터에 더해질 것이며, 각 차원에 대한 평행 이동을 나타냅니다. 첫 번째 요소는 1이고 두 번째 요소는 2입니다.
  4. data = torch.matmul(X, A) + b: data는 행렬 X를 행렬 A로 변환하고 벡터 b를 더한 결과입니다. 이것은 선형 변환과 평행 이동을 나타내며, 데이터셋 data에 저장됩니다. 즉, X의 각 데이터 포인트에 대해 선형 변환과 평행 이동이 수행되어 최종 데이터셋이 생성됩니다.

이 코드는 데이터를 생성하는 과정을 보여주며, 이 데이터는 GAN 또는 다른 딥 러닝 모델을 학습하고 실험하는 데 사용될 수 있습니다.

 

Let’s see what we got. This should be a Gaussian shifted in some rather arbitrary way with mean b and covariance matrix A**T A.

 

우리가 무엇을 얻었는지 봅시다. 이는 평균 b 및 공분산 행렬 A**T A를 사용하여 다소 임의적인 방식으로 이동된 가우스여야 합니다.

 

d2l.set_figsize()
d2l.plt.scatter(data[:100, (0)].detach().numpy(), data[:100, (1)].detach().numpy());
print(f'The covariance matrix is\n{torch.matmul(A.T, A)}')
  1. d2l.set_figsize(): 이 함수는 "Dive into Deep Learning" 라이브러리인 d2l을 사용하여 그림의 크기를 설정합니다. 이 코드에서는 그림 크기를 미리 설정하여 플롯을 만들 때 적절한 크기로 설정합니다.
  2. d2l.plt.scatter(data[:100, (0)].detach().numpy(), data[:100, (1)].detach().numpy()): 이 코드는 데이터를 산점도로 표시합니다. data에서 처음 100개의 데이터 포인트에 대해 두 번째 차원과 세 번째 차원의 값을 가져와서 산점도를 그립니다. detach().numpy()는 텐서를 넘파이 배열로 변환하는 작업입니다.
  3. print(f'The covariance matrix is\n{torch.matmul(A.T, A)}'): 이 코드는 주어진 행렬 A의 전치 행렬과 A 자체를 곱한 결과를 출력합니다. 이것은 데이터의 공분산 행렬을 나타내며, 출력 메시지에 포함됩니다.

이 코드는 데이터의 분포를 시각화하고 해당 데이터의 공분산을 계산하여 출력하는 역할을 합니다. 이를 통해 데이터의 특성과 분포를 파악할 수 있습니다.

 

The covariance matrix is
tensor([[1.0100, 1.9500],
        [1.9500, 4.2500]])

batch_size = 8
data_iter = d2l.load_array((data,), batch_size)
  1. batch_size = 8: 이 코드 라인은 미니배치의 크기를 8로 설정합니다. 미니배치는 한 번에 모델에 입력되는 데이터의 일부분을 나타냅니다. 여기서는 8개의 데이터 포인트로 구성된 미니배치를 사용하겠다는 것을 의미합니다.
  2. data_iter = d2l.load_array((data,), batch_size): 이 코드 라인은 d2l 라이브러리의 load_array 함수를 사용하여 데이터를 미니배치로 나누는 데이터 반복자를 생성합니다. load_array 함수는 데이터를 가져와서 지정한 배치 크기로 나누고, 각 미니배치를 생성하는데 사용됩니다. 이 데이터 반복자(data_iter)를 사용하면 모델을 학습할 때 미니배치 단위로 데이터를 처리할 수 있습니다.

즉, 이 코드는 데이터를 작은 배치로 분할하고, 각 미니배치에 대한 반복자(data_iter)를 생성하는 과정을 나타냅니다. 이것은 모델 학습 및 평가에서 사용되는 일반적인 데이터 처리 방법 중 하나입니다.

 

20.1.2. Generator

Our generator network will be the simplest network possible - a single layer linear model. This is since we will be driving that linear network with a Gaussian data generator. Hence, it literally only needs to learn the parameters to fake things perfectly.

 

우리의 생성기 네트워크는 가능한 가장 간단한 네트워크, 즉 단일 레이어 선형 모델이 될 것입니다. 이는 가우스 데이터 생성기를 사용하여 선형 네트워크를 구동할 것이기 때문입니다. 따라서 말 그대로 완벽하게 가짜를 만들기 위한 매개변수만 학습하면 됩니다.

 

net_G = nn.Sequential(nn.Linear(2, 2))
  1. nn.Sequential: 파이토치의 nn.Sequential은 뉴럴 네트워크의 일련의 연속적인 레이어를 정의하는 컨테이너입니다. 이 컨테이너를 사용하면 각 레이어를 순차적으로 쌓을 수 있습니다.
  2. nn.Linear(2, 2): 이 부분은 nn.Sequential 내부에 추가될 첫 번째 레이어입니다. nn.Linear는 선형 변환을 수행하는 레이어로, 입력 차원과 출력 차원을 지정합니다. 여기서는 입력 차원이 2이고 출력 차원이 2인 선형 레이어를 정의합니다. 즉, 이 생성자 신경망은 2차원의 입력을 받아 2차원의 출력을 생성합니다.

이 코드는 간단한 생성자 신경망을 정의하는데 사용됩니다. GAN(Generative Adversarial Network)에서 생성자는 무작위 노이즈를 입력으로 받아 원하는 형태의 데이터를 생성하는 역할을 합니다. 이 코드에서는 입력 차원과 출력 차원이 모두 2로 설정되었으므로, 이 생성자는 2차원의 데이터를 생성하는 데 사용될 것입니다.

 

20.1.3. Discriminator

For the discriminator we will be a bit more discriminating: we will use an MLP with 3 layers to make things a bit more interesting.

 

판별자의 경우 좀 더 판별할 것입니다. 3개 레이어가 있는 MLP를 사용하여 좀 더 흥미롭게 만들 것입니다.

 

net_D = nn.Sequential(
    nn.Linear(2, 5), nn.Tanh(),
    nn.Linear(5, 3), nn.Tanh(),
    nn.Linear(3, 1))
  1. nn.Sequential: 파이토치의 nn.Sequential은 뉴럴 네트워크의 일련의 연속적인 레이어를 정의하는 컨테이너입니다. 이 컨테이너를 사용하면 각 레이어를 순차적으로 쌓을 수 있습니다.
  2. nn.Linear(2, 5): 이 부분은 nn.Sequential 내부에 추가될 첫 번째 레이어입니다. nn.Linear는 선형 변환을 수행하는 레이어로, 입력 차원과 출력 차원을 지정합니다. 여기서는 입력 차원이 2이고 출력 차원이 5인 선형 레이어를 정의합니다. 이 레이어는 입력 데이터를 5차원 공간으로 변환합니다.
  3. nn.Tanh(): 이는 하이퍼볼릭 탄젠트 활성화 함수를 나타냅니다. 이 활성화 함수는 레이어의 출력을 -1과 1 사이로 변환합니다.
  4. 이어지는 nn.Linear, nn.Tanh() 레이어들은 비슷한 방식으로 연결됩니다. 두 번째 레이어는 5차원을 3차원으로, 세 번째 레이어는 3차원을 1차원으로 변환합니다.

이 코드는 간단한 판별자 신경망을 정의하는데 사용됩니다. GAN(Generative Adversarial Network)에서 판별자는 생성된 데이터와 실제 데이터를 구분하는 역할을 합니다. 이 판별자는 2차원의 입력을 받아 하이퍼볼릭 탄젠트를 사용하여 비선형 변환을 수행하고, 여러 레이어를 통해 데이터를 1차원 출력으로 분류합니다.

 

20.1.4. Training

First we define a function to update the discriminator.

 

먼저 판별자를 업데이트하는 함수를 정의합니다.

 

#@save
def update_D(X, Z, net_D, net_G, loss, trainer_D):
    """Update discriminator."""
    batch_size = X.shape[0]
    ones = torch.ones((batch_size,), device=X.device)
    zeros = torch.zeros((batch_size,), device=X.device)
    trainer_D.zero_grad()
    real_Y = net_D(X)
    fake_X = net_G(Z)
    # Do not need to compute gradient for `net_G`, detach it from
    # computing gradients.
    fake_Y = net_D(fake_X.detach())
    loss_D = (loss(real_Y, ones.reshape(real_Y.shape)) +
              loss(fake_Y, zeros.reshape(fake_Y.shape))) / 2
    loss_D.backward()
    trainer_D.step()
    return loss_D

 

  1. def update_D(X, Z, net_D, net_G, loss, trainer_D): 이 함수는 판별자 네트워크를 업데이트하는 역할을 합니다. 이 함수는 다음 매개변수들을 입력으로 받습니다.
    • X: 실제 데이터 샘플 배치
    • Z: 생성자 네트워크에 의해 생성된 가짜 데이터 샘플 배치
    • net_D: 판별자 네트워크
    • net_G: 생성자 네트워크
    • loss: 손실 함수
    • trainer_D: 판별자 네트워크를 최적화하기 위한 옵티마이저
  2. batch_size = X.shape[0]: 배치 크기를 구합니다. 이는 입력 데이터 X의 첫 번째 차원인 배치 차원의 크기입니다.
  3. ones = torch.ones((batch_size,), device=X.device): 길이가 batch_size인 1로 채워진 텐서를 생성합니다. 이 텐서는 실제 데이터에 대한 레이블로 사용됩니다. device 매개변수는 텐서를 어느 장치 (예: CPU 또는 GPU)에서 계산할 것인지를 지정합니다.
  4. zeros = torch.zeros((batch_size,), device=X.device): 길이가 batch_size인 0으로 채워진 텐서를 생성합니다. 이 텐서는 가짜 데이터에 대한 레이블로 사용됩니다.
  5. trainer_D.zero_grad(): 판별자 네트워크의 그래디언트를 초기화합니다. 이는 새로운 그래디언트를 계산하기 전에 이전 그래디언트를 제거하는데 사용됩니다.
  6. real_Y = net_D(X): 실제 데이터 X를 판별자 네트워크에 전달하여 실제 데이터의 판별 결과를 계산합니다.
  7. fake_X = net_G(Z): 생성자 네트워크에 의해 생성된 가짜 데이터 Z를 판별자 네트워크에 전달하여 가짜 데이터의 판별 결과를 계산합니다.
  8. fake_Y = net_D(fake_X.detach()): 생성자 네트워크에 의해 생성된 가짜 데이터 fake_X를 판별자 네트워크에 전달합니다. .detach()를 사용하여 생성자 네트워크의 그래디언트를 계산하지 않도록 설정합니다.
  9. loss_D = (loss(real_Y, ones.reshape(real_Y.shape)) + loss(fake_Y, zeros.reshape(fake_Y.shape))) / 2: 실제 데이터와 가짜 데이터에 대한 판별자의 손실을 계산합니다. 이 손실은 실제 데이터의 판별 결과와 1 사이의 손실, 그리고 가짜 데이터의 판별 결과와 0 사이의 손실을 평균화한 것입니다.
  10. loss_D.backward(): 판별자 네트워크의 손실에 대한 그래디언트를 계산합니다.
  11. trainer_D.step(): 판별자 네트워크의 매개변수를 업데이트합니다. 최적화된 그래디언트를 사용하여 신경망의 매개변수를 조정합니다.
  12. return loss_D: 계산된 판별자의 손실을 반환합니다.

이 함수는 GAN의 판별자 네트워크를 학습하기 위해 사용되며, 생성자와 판별자 사이의 경쟁을 통해 모델을 훈련시키는 데 필요합니다.

 

The generator is updated similarly. Here we reuse the cross-entropy loss but change the label of the fake data from 0 to 1.

 

생성기도 비슷하게 업데이트됩니다. 여기서는 교차 엔트로피 손실을 재사용하지만 가짜 데이터의 레이블을 0에서 1로 변경합니다.

 

#@save
def update_G(Z, net_D, net_G, loss, trainer_G):
    """Update generator."""
    batch_size = Z.shape[0]
    ones = torch.ones((batch_size,), device=Z.device)
    trainer_G.zero_grad()
    # We could reuse `fake_X` from `update_D` to save computation
    fake_X = net_G(Z)
    # Recomputing `fake_Y` is needed since `net_D` is changed
    fake_Y = net_D(fake_X)
    loss_G = loss(fake_Y, ones.reshape(fake_Y.shape))
    loss_G.backward()
    trainer_G.step()
    return loss_G
  1. def update_G(Z, net_D, net_G, loss, trainer_G): 이 함수는 생성자 네트워크를 업데이트하는 역할을 합니다. 이 함수는 다음 매개변수들을 입력으로 받습니다.
    • Z: 생성자 네트워크의 입력으로 사용될 무작위 노이즈 벡터 배치
    • net_D: 판별자 네트워크
    • net_G: 생성자 네트워크
    • loss: 손실 함수
    • trainer_G: 생성자 네트워크를 최적화하기 위한 옵티마이저
  2. batch_size = Z.shape[0]: 배치 크기를 구합니다. 이는 입력 데이터 Z의 첫 번째 차원인 배치 차원의 크기입니다.
  3. ones = torch.ones((batch_size,), device=Z.device): 길이가 batch_size인 1로 채워진 텐서를 생성합니다. 이 텐서는 생성자가 생성한 데이터에 대한 레이블로 사용됩니다. device 매개변수는 텐서를 어느 장치 (예: CPU 또는 GPU)에서 계산할 것인지를 지정합니다.
  4. trainer_G.zero_grad(): 생성자 네트워크의 그래디언트를 초기화합니다. 이는 새로운 그래디언트를 계산하기 전에 이전 그래디언트를 제거하는데 사용됩니다.
  5. fake_X = net_G(Z): 생성자 네트워크에 무작위 노이즈 Z를 전달하여 가짜 데이터를 생성합니다.
  6. fake_Y = net_D(fake_X): 생성된 가짜 데이터 fake_X를 판별자 네트워크에 전달하여 가짜 데이터의 판별 결과를 계산합니다. 이 부분은 판별자를 통해 가짜 데이터를 판별한 결과입니다.
  7. loss_G = loss(fake_Y, ones.reshape(fake_Y.shape)): 생성자의 손실을 계산합니다. 이 손실은 생성자가 생성한 가짜 데이터에 대한 판별자의 출력과 1 사이의 손실을 나타냅니다. 생성자는 판별자를 속이려고 노력하며, 따라서 이 손실을 최소화하려고 합니다.
  8. loss_G.backward(): 생성자 네트워크의 손실에 대한 그래디언트를 계산합니다.
  9. trainer_G.step(): 생성자 네트워크의 매개변수를 업데이트합니다. 최적화된 그래디언트를 사용하여 신경망의 매개변수를 조정합니다.
  10. return loss_G: 계산된 생성자의 손실을 반환합니다.

이 함수는 GAN의 생성자 네트워크를 학습하기 위해 사용됩니다. 생성자는 판별자를 속이려고 하며, 이를 통해 실제와 유사한 데이터를 생성하도록 훈련됩니다.

 

Both the discriminator and the generator performs a binary logistic regression with the cross-entropy loss. We use Adam to smooth the training process. In each iteration, we first update the discriminator and then the generator. We visualize both losses and generated examples.

 

판별자와 생성자 모두 교차 엔트로피 손실을 사용하여 이진 로지스틱 회귀를 수행합니다. 우리는 훈련 과정을 원활하게 하기 위해 Adam을 사용합니다. 각 반복에서 먼저 판별자를 업데이트한 다음 생성자를 업데이트합니다. 손실과 생성된 사례를 모두 시각화합니다.

 

def train(net_D, net_G, data_iter, num_epochs, lr_D, lr_G, latent_dim, data):
    loss = nn.BCEWithLogitsLoss(reduction='sum')
    for w in net_D.parameters():
        nn.init.normal_(w, 0, 0.02)
    for w in net_G.parameters():
        nn.init.normal_(w, 0, 0.02)
    trainer_D = torch.optim.Adam(net_D.parameters(), lr=lr_D)
    trainer_G = torch.optim.Adam(net_G.parameters(), lr=lr_G)
    animator = d2l.Animator(xlabel='epoch', ylabel='loss',
                            xlim=[1, num_epochs], nrows=2, figsize=(5, 5),
                            legend=['discriminator', 'generator'])
    animator.fig.subplots_adjust(hspace=0.3)
    for epoch in range(num_epochs):
        # Train one epoch
        timer = d2l.Timer()
        metric = d2l.Accumulator(3)  # loss_D, loss_G, num_examples
        for (X,) in data_iter:
            batch_size = X.shape[0]
            Z = torch.normal(0, 1, size=(batch_size, latent_dim))
            metric.add(update_D(X, Z, net_D, net_G, loss, trainer_D),
                       update_G(Z, net_D, net_G, loss, trainer_G),
                       batch_size)
        # Visualize generated examples
        Z = torch.normal(0, 1, size=(100, latent_dim))
        fake_X = net_G(Z).detach().numpy()
        animator.axes[1].cla()
        animator.axes[1].scatter(data[:, 0], data[:, 1])
        animator.axes[1].scatter(fake_X[:, 0], fake_X[:, 1])
        animator.axes[1].legend(['real', 'generated'])
        # Show the losses
        loss_D, loss_G = metric[0]/metric[2], metric[1]/metric[2]
        animator.add(epoch + 1, (loss_D, loss_G))
    print(f'loss_D {loss_D:.3f}, loss_G {loss_G:.3f}, '
          f'{metric[2] / timer.stop():.1f} examples/sec')

이 함수는 GAN 모델을 훈련하는 주요 루프를 포함하고 있습니다. 주요 단계는 다음과 같습니다.

  1. BCEWithLogitsLoss를 사용하여 손실 함수를 설정합니다. 이 손실 함수는 이진 분류 손실 함수로 사용됩니다.
  2. 판별자와 생성자 네트워크의 가중치를 초기화합니다. 일반적으로 작은 랜덤값으로 초기화합니다.
  3. Adam 옵티마이저를 설정하여 판별자와 생성자 네트워크의 매개변수를 최적화합니다.
  4. 애니메이터를 설정하여 훈련 중에 손실과 생성된 데이터를 시각화합니다.
  5. 주어진 에포크 수(num_epochs) 동안 훈련 루프를 실행합니다. 각 에포크에서는 판별자와 생성자 네트워크를 업데이트하고 손실을 누적합니다.
  6. 생성된 예제를 시각화하여 실제 데이터와 비교합니다.
  7. 각 에포크의 손실을 기록하고 애니메이터를 통해 시각화합니다.
  8. 훈련이 끝난 후 최종 손실과 훈련 속도를 출력합니다.

이 함수를 호출하여 GAN 모델을 훈련하고 결과를 시각화할 수 있습니다.

 

Now we specify the hyperparameters to fit the Gaussian distribution.

 

이제 가우스 분포에 맞게 하이퍼파라미터를 지정합니다.

 

lr_D, lr_G, latent_dim, num_epochs = 0.05, 0.005, 2, 20
train(net_D, net_G, data_iter, num_epochs, lr_D, lr_G,
      latent_dim, data[:100].detach().numpy())
  1. lr_D, lr_G, latent_dim, num_epochs: 이 코드 라인에서는 GAN 모델을 훈련하는데 사용되는 하이퍼파라미터를 설정합니다.
    • lr_D: 판별자 네트워크를 최적화하는 데 사용되는 학습률입니다.
    • lr_G: 생성자 네트워크를 최적화하는 데 사용되는 학습률입니다.
    • latent_dim: 생성자의 입력 노이즈 벡터의 차원입니다.
    • num_epochs: 훈련하는 데 사용할 에포크(훈련 주기) 수입니다.
  2. train(net_D, net_G, data_iter, num_epochs, lr_D, lr_G, latent_dim, data[:100].detach().numpy()): 이 코드 라인에서는 train 함수를 호출하여 GAN 모델을 실제로 훈련합니다.
    • net_D: 판별자 네트워크
    • net_G: 생성자 네트워크
    • data_iter: 데이터 반복자
    • num_epochs: 설정한 에포크 수
    • lr_D, lr_G: 판별자와 생성자의 학습률
    • latent_dim: 생성자의 입력 노이즈 벡터의 차원
    • data[:100].detach().numpy(): 사용할 데이터 중에서 처음 100개의 데이터를 선택하고 넘파이 배열로 변환한 것입니다. GAN 모델을 훈련할 때는 실제 데이터의 일부만 사용하여 훈련합니다.

이 코드를 실행하면 GAN 모델이 주어진 데이터에 대해 훈련되고, 훈련 과정 중에 손실이 감소하면서 생성된 가짜 데이터가 실제 데이터와 유사해지는 것을 관찰할 수 있습니다.

loss_D 0.693, loss_G 0.693, 1020.0 examples/sec

20.1.5. Summary

  • Generative adversarial networks (GANs) composes of two deep networks, the generator and the discriminator.

  • GAN(Generative Adversarial Network)은 생성자와 판별자라는 두 개의 심층 네트워크로 구성됩니다.

  • The generator generates the image as much closer to the true image as possible to fool the discriminator, via maximizing the cross-entropy loss, i.e., maxlog⁡(D(x′)).

  • 생성기는 교차 엔트로피 손실(예: maxlog⁡(D(x′)))을 최대화하여 판별기를 속이기 위해 가능한 한 실제 이미지에 더 가까운 이미지를 생성합니다.

  • The discriminator tries to distinguish the generated images from the true images, via minimizing the cross-entropy loss, i.e., min−y log⁡D(x)−(1−y)log⁡(1−D(x)).

  • 판별자는 교차 엔트로피 손실, 즉 min−y log⁡D(x)−(1−y)log⁡(1−D(x))를 최소화하여 생성된 이미지를 실제 이미지와 구별하려고 시도합니다.

 

20.1.6. Exercises

  • Does an equilibrium exist where the generator wins, i.e. the discriminator ends up unable to distinguish the two distributions on finite samples?

  • 생성자가 승리하는 평형이 존재합니까? 즉, 판별자가 유한 샘플에서 두 분포를 구별할 수 없게 됩니까?

https://youtu.be/odpjk7_tGY0?si=VdPZUy_pliDQuy9s 

https://youtu.be/AVvlDmhHgC4?si=NdxDspK0LVNwpV8H 

 

 

 

 

 

 

 

 

 

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/sh-async.html

 

19.5. Asynchronous Successive Halving — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.5. Asynchronous Successive Halving

 

As we have seen in Section 19.3, we can accelerate HPO by distributing the evaluation of hyperparameter configurations across either multiple instances or multiples CPUs / GPUs on a single instance. However, compared to random search, it is not straightforward to run successive halving (SH) asynchronously in a distributed setting. Before we can decide which configuration to run next, we first have to collect all observations at the current rung level. This requires to synchronize workers at each rung level. For example, for the lowest rung level r min, we first have to evaluate all N=η**k configurations, before we can promote the 1/η of them to the next rung level.

 

섹션 19.3에서 살펴본 것처럼 하이퍼파라미터 구성 평가를 여러 인스턴스 또는 단일 인스턴스의 여러 CPU/GPU에 분산하여 HPO를 가속화할 수 있습니다. 그러나 무작위 검색에 비해 분산 설정에서 비동기적으로 연속 반감기(SH)를 실행하는 것은 간단하지 않습니다. 다음에 실행할 구성을 결정하기 전에 먼저 현재 단계 수준에서 모든 관찰을 수집해야 합니다. 이를 위해서는 각 단계 수준에서 작업자를 동기화해야 합니다. 예를 들어, 가장 낮은 단계 수준 r min의 경우 먼저 모든 N=eta**k 구성을 평가해야 그 중 1/eta를 다음 단계 수준으로 승격할 수 있습니다.

 

In any distributed system, synchronization typically implies idle time for workers. First, we often observe high variations in training time across hyperparameter configurations. For example, assuming the number of filters per layer is a hyperparameter, then networks with less filters finish training faster than networks with more filters, which implies idle worker time due to stragglers. Moreover, the number of slots in a rung level is not always a multiple of the number of workers, in which case some workers may even sit idle for a full batch.

 

모든 분산 시스템에서 동기화는 일반적으로 작업자의 유휴 시간을 의미합니다. 첫째, 우리는 하이퍼파라미터 구성 전반에 걸쳐 훈련 시간의 높은 변동을 자주 관찰합니다. 예를 들어, 레이어당 필터 수가 하이퍼파라미터라고 가정하면 필터가 적은 네트워크는 필터가 많은 네트워크보다 훈련을 더 빨리 완료합니다. 이는 낙오자로 인한 유휴 작업자 시간을 의미합니다. 또한 단계 수준의 슬롯 수가 항상 작업자 수의 배수가 되는 것은 아니며, 이 경우 일부 작업자는 전체 배치 동안 유휴 상태로 있을 수도 있습니다.

 

Figure Fig. 19.5.1 shows the scheduling of synchronous SH with η=2 for four different trials with two workers. We start with evaluating Trial-0 and Trial-1 for one epoch and immediately continue with the next two trials once they are finished. We first have to wait until Trial-2 finishes, which takes substantially more time than the other trials, before we can promote the best two trials, i.e., Trial-0 and Trial-3 to the next rung level. This causes idle time for Worker-1. Then, we continue with Rung 1. Also, here Trial-3 takes longer than Trial-0, which leads to an additional ideling time of Worker-0. Once, we reach Rung-2, only the best trial, Trial-0, remains which occupies only one worker. To avoid that Worker-1 idles during that time, most implementaitons of SH continue already with the next round, and start evaluating new trials (e.g Trial-4) on the first rung.

 

그림 그림 19.5.1은 2명의 워커를 사용한 4가지 다른 시도에 대해 θ=2인 동기식 SH의 스케줄링을 보여줍니다. 한 에포크 동안 Trial-0과 Trial-1을 평가하는 것으로 시작하고, 완료되면 다음 두 번의 시도를 즉시 계속합니다. 가장 좋은 두 가지 시도, 즉 Trial-0과 Trial-3을 다음 단계로 승격하려면 먼저 다른 시도보다 훨씬 더 많은 시간이 걸리는 Trial-2가 완료될 때까지 기다려야 합니다. 이로 인해 Worker-1의 유휴 시간이 발생합니다. 그런 다음 Rung 1을 계속 진행합니다. 또한 여기서 Trial-3은 Trial-0보다 시간이 오래 걸리므로 Worker-0의 추가 유휴 시간이 발생합니다. 일단 Rung-2에 도달하면 가장 좋은 시도인 Trial-0만 남고 작업자는 한 명만 차지합니다. 해당 시간 동안 Worker-1이 유휴 상태가 되는 것을 방지하기 위해 대부분의 SH 구현은 이미 다음 라운드에서 계속되고 첫 번째 단계에서 새로운 시도(예: Trial-4) 평가를 시작합니다.

 

Fig. 19.5.1  Synchronous successive halving with two workers.

 

Asynchronous successive halving (ASHA) (Li et al., 2018) adapts SH to the asynchronous parallel scenario. The main idea of ASHA is to promote configurations to the next rung level as soon as we collected at least η observations on the current rung level. This decision rule may lead to suboptimal promotions: configurations can be promoted to the next rung level, which in hindsight do not compare favourably against most others at the same rung level. On the other hand, we get rid of all synchronization points this way. In practice, such suboptimal initial promotions have only a modest impact on performance, not only because the ranking of hyperparameter configurations is often fairly consistent across rung levels, but also because rungs grow over time and reflect the distribution of metric values at this level better and better. If a worker is free, but no configuration can be promoted, we start a new configuration with r = r min, i.e the first rung level.

 

비동기 연속 반감기(ASHA)(Li et al., 2018)는 SH를 비동기 병렬 시나리오에 적용합니다. ASHA의 주요 아이디어는 현재 단계 수준에서 최소 eta 관측치를 수집하자마자 구성을 다음 단계 수준으로 승격시키는 것입니다. 이 결정 규칙은 최적이 아닌 승격으로 이어질 수 있습니다. 구성은 다음 단계 수준으로 승격될 수 있으며, 돌이켜보면 동일한 단계 수준의 대부분의 다른 단계와 비교했을 때 호의적이지 않습니다. 반면에 우리는 이런 방식으로 모든 동기화 지점을 제거합니다. 실제로 이러한 최적이 아닌 초기 승격은 성능에 미미한 영향만 미칠 뿐입니다. 이는 초매개변수 구성의 순위가 단계 수준 전체에서 상당히 일관되는 경우가 많을 뿐만 아니라 단계가 시간이 지남에 따라 증가하고 이 수준에서 메트릭 값의 분포를 더 잘 반영하고 더 잘 반영하기 때문입니다. 더 나은. 작업자가 무료이지만 승격할 수 있는 구성이 없으면 r = r min으로 새 구성, 즉 첫 번째 단계 수준을 시작합니다.

 

Fig. 19.5.2 shows the scheduling of the same configurations for ASHA. Once Trial-1 finishes, we collect the results of two trials (i.e Trial-0 and Trial-1) and immediately promote the better of them (Trial-0) to the next rung level. After Trial-0 finishes on rung 1, there are too few trials there in order to support a further promotion. Hence, we continue with rung 0 and evaluate Trial-3. Once Trial-3 finishes, Trial-2 is still pending. At this point we have 3 trials evaluated on rung 0 and one trial evaluated already on rung 1. Since Trial-3 performs worse than Trial-0 at rung 0, and η = 2, we cannot promote any new trial yet, and Worker-1 starts Trial-4 from scratch instead. However, once Trial-2 finishes and scores worse than Trial-3, the latter is promoted towards rung 1. Afterwards, we collected 2 evaluations on rung 1, which means we can now promote Trial-0 towards rung 2. At the same time, Worker-1 continues with evaluating new trials (i.e., Trial-5) on rung 0.

 

그림 19.5.2는 ASHA에 대한 동일한 구성의 스케줄링을 보여줍니다. Trial-1이 완료되면 두 가지 시도(즉, Trial-0 및 Trial-1)의 결과를 수집하고 그 중 더 나은 것(Trial-0)을 즉시 다음 단계 수준으로 승격합니다. 평가판 0이 단계 1에서 끝난 후에는 추가 승격을 지원하기에는 시도 횟수가 너무 적습니다. 따라서 우리는 단계 0을 계속 진행하고 평가판 3을 평가합니다. 평가판 3이 끝나면 평가판 2가 계속 보류됩니다. 이 시점에서 우리는 단계 0에서 평가된 3개의 시도와 단계 1에서 이미 평가된 하나의 시도를 가지고 있습니다. Trial-3은 단계 0에서 Trial-0보다 성능이 떨어지고 θ = 2이므로 아직 새로운 시도를 승격할 수 없으며 Worker- 1은 대신 Trial-4를 처음부터 시작합니다. 그러나 평가판 2가 완료되고 평가판 3보다 낮은 점수를 받으면 후자는 단계 1로 승격됩니다. 이후 단계 1에서 2개의 평가를 수집했습니다. 이는 이제 평가판 0을 단계 2로 승격할 수 있음을 의미합니다. , 작업자-1은 단계 0에서 새로운 시도(즉, 시도 5)를 계속 평가합니다.

 

Fig. 19.5.2  Asynchronous successive halving (ASHA) with two workers.

 

import logging
from d2l import torch as d2l

logging.basicConfig(level=logging.INFO)
import matplotlib.pyplot as plt
from syne_tune import StoppingCriterion, Tuner
from syne_tune.backend.python_backend import PythonBackend
from syne_tune.config_space import loguniform, randint
from syne_tune.experiments import load_experiment
from syne_tune.optimizer.baselines import ASHA

위의 코드는 HPO(Hyperparameter Optimization) 실험을 수행하기 위한 설정을 위한 코드입니다. 주요 라이브러리와 로깅 설정을 포함하고 있습니다.

  • import logging: 로깅(logging)을 위한 파이썬 라이브러리를 가져옵니다.
  • from d2l import torch as d2l: "d2l" 라이브러리에서 "torch" 모듈을 가져옵니다. 이 모듈은 PyTorch 기반의 딥 러닝 코드 작성을 지원합니다.
  • logging.basicConfig(level=logging.INFO): 로깅 레벨을 INFO로 설정하고 기본 로깅 구성을 초기화합니다. 이를 통해 코드 실행 중에 로그 메시지를 출력할 수 있습니다.
  • import matplotlib.pyplot as plt: Matplotlib을 사용하여 그래프를 그리기 위한 모듈을 가져옵니다.
  • from syne_tune import StoppingCriterion, Tuner: SyneTune 라이브러리에서 StoppingCriterion과 Tuner 클래스를 가져옵니다. 이 클래스들은 HPO 실험을 관리하고 조정하는 데 사용됩니다.
  • from syne_tune.backend.python_backend import PythonBackend: SyneTune에서 사용하는 백엔드(backend) 중 하나인 PythonBackend를 가져옵니다. 백엔드는 HPO 실험을 실행하는 방식을 지정합니다.
  • from syne_tune.config_space import loguniform, randint: HPO 실험에서 사용할 하이퍼파라미터 공간을 정의하기 위해 loguniform과 randint 등의 함수를 가져옵니다. 이 함수들을 사용하여 하이퍼파라미터를 샘플링할 수 있습니다.
  • from syne_tune.experiments import load_experiment: SyneTune에서 실험을 로드하고 관리하기 위한 함수를 가져옵니다.
  • from syne_tune.optimizer.baselines import ASHA: ASHA(Hyperband 기반의 비동기 하이퍼파라미터 최적화 알고리즘)를 가져옵니다. ASHA는 하이퍼파라미터 최적화에 사용되는 알고리즘 중 하나입니다.
INFO:root:SageMakerBackend is not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
INFO:root:Ray Tune schedulers and searchers are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[raytune]'
or (for everything)
   pip install 'syne-tune[extra]'

 

19.5.1. Objective Function

 

We will use Syne Tune with the same objective function as in Section 19.3.

 

섹션 19.3과 동일한 목적 함수를 사용하여 Syne Tune을 사용하겠습니다.

 

def hpo_objective_lenet_synetune(learning_rate, batch_size, max_epochs):
    from syne_tune import Reporter
    from d2l import torch as d2l

    model = d2l.LeNet(lr=learning_rate, num_classes=10)
    trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1)
    data = d2l.FashionMNIST(batch_size=batch_size)
    model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)
    report = Reporter()
    for epoch in range(1, max_epochs + 1):
        if epoch == 1:
            # Initialize the state of Trainer
            trainer.fit(model=model, data=data)
        else:
            trainer.fit_epoch()
        validation_error = trainer.validation_error().cpu().detach().numpy()
        report(epoch=epoch, validation_error=float(validation_error))

위의 코드는 SyneTune 라이브러리를 사용하여 하이퍼파라미터 최적화를 수행하는 목적 함수(hpo_objective_lenet_synetune)를 정의한 부분입니다. 이 함수는 LeNet 아키텍처를 사용하여 이미지 분류 모델을 훈련하고, 각 하이퍼파라미터 설정에 대한 검증 오차(validation error)를 반환합니다.

주요 내용은 다음과 같습니다.

  • learning_rate, batch_size, max_epochs 등의 하이퍼파라미터를 입력으로 받습니다.
  • model = d2l.LeNet(lr=learning_rate, num_classes=10): 주어진 학습률(learning_rate)과 클래스 수(num_classes)를 가지고 LeNet 모델을 생성합니다.
  • trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1): 하이퍼파라미터 최적화를 위한 트레이너를 생성합니다. max_epochs는 1로 설정되어 있으므로 하나의 에포크만 훈련됩니다.
  • data = d2l.FashionMNIST(batch_size=batch_size): Fashion MNIST 데이터셋을 로드하고 주어진 배치 크기(batch_size)로 데이터를 미니배치 형태로 제공합니다.
  • model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn): 초기화 함수 d2l.init_cnn을 사용하여 모델을 초기화합니다.
  • report = Reporter(): 실험 결과를 기록하기 위한 Reporter 객체를 생성합니다.
  • 반복문을 통해 에포크(epoch)를 1부터 max_epochs까지 증가시키면서 모델을 훈련합니다.
  • 에포크가 1인 경우에는 트레이너를 초기화하고 모델을 훈련시킵니다.
  • 에포크가 1보다 큰 경우에는 trainer.fit_epoch()를 호출하여 한 번의 에포크를 추가로 훈련시킵니다.
  • trainer.validation_error().cpu().detach().numpy()를 통해 검증 오차(validation error)를 계산하고 반환합니다.
  • report(epoch=epoch, validation_error=float(validation_error))를 사용하여 현재 에포크와 검증 오차를 Reporter에 기록합니다.

즉, 이 함수는 주어진 하이퍼파라미터 설정으로 모델을 훈련하고 검증 오차를 반환하는 역할을 합니다. SyneTune은 이 함수를 사용하여 다양한 하이퍼파라미터 설정을 시도하고 최적의 설정을 찾습니다.

 

 

We will also use the same configuration space as before:

 

또한 이전과 동일한 구성 공간을 사용합니다.

 

min_number_of_epochs = 2
max_number_of_epochs = 10
eta = 2

config_space = {
    "learning_rate": loguniform(1e-2, 1),
    "batch_size": randint(32, 256),
    "max_epochs": max_number_of_epochs,
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 SyneTune 라이브러리를 사용하여 하이퍼파라미터 최적화를 수행할 때 사용되는 설정과 초기 하이퍼파라미터 값을 정의하는 부분입니다. 주요 내용은 다음과 같습니다.

  • min_number_of_epochs: 실험에서 허용하는 최소 에포크 수입니다. 이 값은 2로 설정되어 있습니다.
  • max_number_of_epochs: 실험에서 허용하는 최대 에포크 수입니다. 이 값은 10으로 설정되어 있습니다.
  • eta: Successive Halving 알고리즘에서 사용되는 파라미터로, 곱셈 연산을 수행할 때 사용됩니다. 이 값은 2로 설정되어 있습니다.
  • config_space: 하이퍼파라미터 공간을 정의하는 부분입니다. 여기서는 세 가지 하이퍼파라미터인 learning_rate, batch_size, max_epochs의 범위를 지정합니다.
    • learning_rate: 로그균등 분포(loguniform distribution)를 사용하여 1e-2에서 1 사이의 값으로 설정됩니다.
    • batch_size: 균등 분포(uniform distribution)를 사용하여 32에서 256 사이의 정수 값으로 설정됩니다.
    • max_epochs: max_number_of_epochs로 설정된 최대 에포크 값을 가집니다.
  • initial_config: 초기 하이퍼파라미터 설정을 정의하는 부분입니다. 여기서는 learning_rate를 0.1로, batch_size를 128로 초기화합니다.

이러한 설정과 초기값은 하이퍼파라미터 최적화 실험을 수행할 때 사용됩니다. SyneTune 라이브러리를 통해 하이퍼파라미터 탐색을 진행하면서 이러한 설정 범위 내에서 하이퍼파라미터 값을 조정하고 최적의 설정을 찾게 됩니다.

 

19.5.2. Asynchronous Scheduler

 

First, we define the number of workers that evaluate trials concurrently. We also need to specify how long we want to run random search, by defining an upper limit on the total wall-clock time.

 

먼저, 동시에 시험을 평가하는 작업자 수를 정의합니다. 또한 총 벽시계 시간의 상한을 정의하여 무작위 검색을 실행할 기간을 지정해야 합니다.

 

n_workers = 2  # Needs to be <= the number of available GPUs
max_wallclock_time = 12 * 60  # 12 minutes

위의 코드는 하이퍼파라미터 최적화 실험을 수행할 때 사용되는 두 가지 중요한 설정을 나타냅니다.

  • n_workers: 실험 도중에 병렬로 실행되는 워커(작업자)의 수를 나타냅니다. 이 수는 사용 가능한 GPU 수보다 작거나 같아야 합니다. 여기서는 2로 설정되어 있으므로 최대 2개의 GPU 또는 병렬 작업자를 사용할 수 있음을 의미합니다.
  • max_wallclock_time: 하이퍼파라미터 최적화 실험의 최대 시간을 분 단위로 나타냅니다. 이 값은 12 * 60으로 설정되어 있으므로 최대 12시간(720분) 동안 실험을 진행할 수 있음을 의미합니다. 실험 시간이 이 설정 값 이내에 끝나도록 실험을 조절합니다.

 

The code for running ASHA is a simple variation of what we did for asynchronous random search.

 

ASHA를 실행하기 위한 코드는 비동기 무작위 검색을 위해 수행한 작업의 간단한 변형입니다.

 

mode = "min"
metric = "validation_error"
resource_attr = "epoch"

scheduler = ASHA(
    config_space,
    metric=metric,
    mode=mode,
    points_to_evaluate=[initial_config],
    max_resource_attr="max_epochs",
    resource_attr=resource_attr,
    grace_period=min_number_of_epochs,
    reduction_factor=eta,
)

위의 코드는 하이퍼파라미터 최적화 실험에서 사용되는 스케줄러인 ASHA (Asynchronous Successive Halving Algorithm)를 설정하는 부분입니다.

  • mode: ASHA 알고리즘에서 최적화할 메트릭의 모드를 나타냅니다. "min"으로 설정되어 있으므로 이 알고리즘은 가장 낮은 값을 찾는 데 초점을 맞추게 됩니다.
  • metric: ASHA 알고리즘에서 최적화할 메트릭의 이름을 나타냅니다. 이 경우 "validation_error"로 설정되어 있으므로 검증 오차(validation error)를 최소화하려고 시도합니다.
  • resource_attr: 실험에서 사용할 리소스 속성을 나타냅니다. 여기서는 "epoch"으로 설정되어 있으므로 에포크(epoch) 수를 리소스로 사용하여 하이퍼파라미터 최적화를 수행합니다.
  • max_resource_attr: ASHA 알고리즘에서 사용할 최대 리소스 속성을 지정합니다. 이 경우 "max_epochs"로 설정되어 있으므로 최대 에포크 수가 사용됩니다.
  • grace_period: ASHA 알고리즘에서 고려할 하이퍼파라미터를 선택하는데 필요한 최소 리소스 수를 나타냅니다. 이 값은 "min_number_of_epochs"로 설정되어 있으므로 최소 에포크 수만큼 리소스가 할당된 경우에만 하이퍼파라미터가 선택됩니다.
  • reduction_factor: ASHA 알고리즘에서 에포크 수를 줄이는 비율을 나타냅니다. 이 값은 "eta"로 설정되어 있으므로 2입니다. 이것은 각 라운드에서 절반씩 에포크 수를 줄이는 것을 의미합니다.

ASHA 스케줄러는 하이퍼파라미터 최적화를 수행하는 데 사용되며, 리소스 속성을 기반으로 하이퍼파라미터 검색을 조절하는 데 도움을 줍니다.

INFO:syne_tune.optimizer.schedulers.fifo:max_resource_level = 10, as inferred from config_space
INFO:syne_tune.optimizer.schedulers.fifo:Master random_seed = 3140976097

 

Here, metric and resource_attr specify the key names used with the report callback, and max_resource_attr denotes which input to the objective function corresponds to r max. Moreover, grace_period provides r min, and reduction_factor is η. We can run Syne Tune as before (this will take about 12 minutes):

 

여기에서 metric 및 resources_attr은 보고서 콜백과 함께 사용되는 키 이름을 지정하고 max_resource_attr은 목적 함수에 대한 입력이 r max에 해당하는지 나타냅니다. 또한, Grace_기간은 r min을 제공하고, 감소_인자는 θ입니다. 이전과 같이 Syne Tune을 실행할 수 있습니다(약 12분 소요).

 

trial_backend = PythonBackend(
    tune_function=hpo_objective_lenet_synetune,
    config_space=config_space,
)

stop_criterion = StoppingCriterion(max_wallclock_time=max_wallclock_time)
tuner = Tuner(
    trial_backend=trial_backend,
    scheduler=scheduler,
    stop_criterion=stop_criterion,
    n_workers=n_workers,
    print_update_interval=int(max_wallclock_time * 0.6),
)
tuner.run()

위의 코드는 ASHA 스케줄러를 사용하여 하이퍼파라미터 최적화 실험을 실행하는 부분입니다.

  • trial_backend: 실험을 실행하는 백엔드(Backend)를 설정합니다. 여기서는 PythonBackend를 사용하며, tune_function에는 hpo_objective_lenet_synetune 함수를, config_space에는 하이퍼파라미터 검색 공간을 설정합니다. 이 백엔드는 Python 함수를 호출하여 실험을 실행합니다.
  • stop_criterion: ASHA 스케줄러를 중지시키는 기준을 설정합니다. max_wallclock_time은 실험을 실행할 최대 시간(분)을 설정하며, 이 값은 12 * 60으로 설정되어 있으므로 12분 동안 실험을 실행한 후 중지됩니다.
  • tuner: Tuner 클래스를 사용하여 최적화 프로세스를 설정합니다. trial_backend에는 백엔드 설정, scheduler에는 ASHA 스케줄러, stop_criterion에는 중지 기준, n_workers에는 사용할 워커(실험 실행 프로세스) 수를 설정합니다. print_update_interval은 중간 업데이트를 출력하는 간격을 설정하며, max_wallclock_time의 60%에 해당하는 값으로 설정됩니다.
  • tuner.run(): 이 명령은 하이퍼파라미터 최적화 실험을 실행합니다. ASHA 스케줄러를 사용하여 여러 하이퍼파라미터 조합을 평가하고 최적의 하이퍼파라미터를 찾습니다. 실험이 실행되는 동안 중간 업데이트가 출력됩니다.
INFO:syne_tune.tuner:results of trials will be saved on /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046
INFO:root:Detected 4 GPUs
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1 --batch_size 128 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/0/checkpoints
INFO:syne_tune.tuner:(trial 0) - scheduled config {'learning_rate': 0.1, 'batch_size': 128, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.44639554136672527 --batch_size 196 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/1/checkpoints
INFO:syne_tune.tuner:(trial 1) - scheduled config {'learning_rate': 0.44639554136672527, 'batch_size': 196, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.011548051321691994 --batch_size 254 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/2/checkpoints
INFO:syne_tune.tuner:(trial 2) - scheduled config {'learning_rate': 0.011548051321691994, 'batch_size': 254, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.14942487313193167 --batch_size 132 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/3/checkpoints
INFO:syne_tune.tuner:(trial 3) - scheduled config {'learning_rate': 0.14942487313193167, 'batch_size': 132, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 1 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.06317157191455719 --batch_size 242 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/4/checkpoints
INFO:syne_tune.tuner:(trial 4) - scheduled config {'learning_rate': 0.06317157191455719, 'batch_size': 242, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.48801815412811467 --batch_size 41 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/5/checkpoints
INFO:syne_tune.tuner:(trial 5) - scheduled config {'learning_rate': 0.48801815412811467, 'batch_size': 41, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.5904067586747807 --batch_size 244 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/6/checkpoints
INFO:syne_tune.tuner:(trial 6) - scheduled config {'learning_rate': 0.5904067586747807, 'batch_size': 244, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.08812857364095393 --batch_size 148 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/7/checkpoints
INFO:syne_tune.tuner:(trial 7) - scheduled config {'learning_rate': 0.08812857364095393, 'batch_size': 148, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.012271314788363914 --batch_size 235 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/8/checkpoints
INFO:syne_tune.tuner:(trial 8) - scheduled config {'learning_rate': 0.012271314788363914, 'batch_size': 235, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 5 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.08845692598296777 --batch_size 236 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/9/checkpoints
INFO:syne_tune.tuner:(trial 9) - scheduled config {'learning_rate': 0.08845692598296777, 'batch_size': 236, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.0825770880068151 --batch_size 75 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/10/checkpoints
INFO:syne_tune.tuner:(trial 10) - scheduled config {'learning_rate': 0.0825770880068151, 'batch_size': 75, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.20235201406823256 --batch_size 65 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/11/checkpoints
INFO:syne_tune.tuner:(trial 11) - scheduled config {'learning_rate': 0.20235201406823256, 'batch_size': 65, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.3359885631737537 --batch_size 58 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/12/checkpoints
INFO:syne_tune.tuner:(trial 12) - scheduled config {'learning_rate': 0.3359885631737537, 'batch_size': 58, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.7892434579795236 --batch_size 89 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/13/checkpoints
INFO:syne_tune.tuner:(trial 13) - scheduled config {'learning_rate': 0.7892434579795236, 'batch_size': 89, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1233786579597858 --batch_size 176 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/14/checkpoints
INFO:syne_tune.tuner:(trial 14) - scheduled config {'learning_rate': 0.1233786579597858, 'batch_size': 176, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 13 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.13707981127012328 --batch_size 141 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/15/checkpoints
INFO:syne_tune.tuner:(trial 15) - scheduled config {'learning_rate': 0.13707981127012328, 'batch_size': 141, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.02913976299993913 --batch_size 116 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/16/checkpoints
INFO:syne_tune.tuner:(trial 16) - scheduled config {'learning_rate': 0.02913976299993913, 'batch_size': 116, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.033362897489792855 --batch_size 154 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/17/checkpoints
INFO:syne_tune.tuner:(trial 17) - scheduled config {'learning_rate': 0.033362897489792855, 'batch_size': 154, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.29442952580755816 --batch_size 210 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/18/checkpoints
INFO:syne_tune.tuner:(trial 18) - scheduled config {'learning_rate': 0.29442952580755816, 'batch_size': 210, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.10214259921521483 --batch_size 239 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/19/checkpoints
INFO:syne_tune.tuner:(trial 19) - scheduled config {'learning_rate': 0.10214259921521483, 'batch_size': 239, 'max_epochs': 10}
INFO:syne_tune.tuner:tuning status (last metric is reported)
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0    Stopped     4       0.100000         128          10    4.0          0.430578    29.093798
        1  Completed    10       0.446396         196          10   10.0          0.205652    72.747496
        2    Stopped     2       0.011548         254          10    2.0          0.900570    13.729115
        3    Stopped     8       0.149425         132          10    8.0          0.259171    58.980305
        4    Stopped     4       0.063172         242          10    4.0          0.900579    27.773950
        5  Completed    10       0.488018          41          10   10.0          0.140488   113.171314
        6    Stopped    10       0.590407         244          10   10.0          0.193776    70.364757
        7    Stopped     2       0.088129         148          10    2.0          0.899955    14.169738
        8    Stopped     2       0.012271         235          10    2.0          0.899840    13.434274
        9    Stopped     2       0.088457         236          10    2.0          0.899801    13.034437
       10    Stopped     4       0.082577          75          10    4.0          0.385970    35.426524
       11    Stopped     4       0.202352          65          10    4.0          0.543102    34.653495
       12    Stopped    10       0.335989          58          10   10.0          0.149558    90.924182
       13  Completed    10       0.789243          89          10   10.0          0.144887    77.365970
       14    Stopped     2       0.123379         176          10    2.0          0.899987    12.422906
       15    Stopped     2       0.137080         141          10    2.0          0.899983    13.395153
       16    Stopped     4       0.029140         116          10    4.0          0.900532    27.834111
       17    Stopped     2       0.033363         154          10    2.0          0.899996    13.407285
       18 InProgress     1       0.294430         210          10    1.0          0.899878     6.126259
       19 InProgress     0       0.102143         239          10      -                 -            -
2 trials running, 18 finished (3 until the end), 437.07s wallclock-time

INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.02846298236356246 --batch_size 115 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/20/checkpoints
INFO:syne_tune.tuner:(trial 20) - scheduled config {'learning_rate': 0.02846298236356246, 'batch_size': 115, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.037703019195187606 --batch_size 91 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/21/checkpoints
INFO:syne_tune.tuner:(trial 21) - scheduled config {'learning_rate': 0.037703019195187606, 'batch_size': 91, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.0741039859356903 --batch_size 192 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/22/checkpoints
INFO:syne_tune.tuner:(trial 22) - scheduled config {'learning_rate': 0.0741039859356903, 'batch_size': 192, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.3032613031191755 --batch_size 252 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/23/checkpoints
INFO:syne_tune.tuner:(trial 23) - scheduled config {'learning_rate': 0.3032613031191755, 'batch_size': 252, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.019823425532533637 --batch_size 252 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/24/checkpoints
INFO:syne_tune.tuner:(trial 24) - scheduled config {'learning_rate': 0.019823425532533637, 'batch_size': 252, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.8203370335228594 --batch_size 77 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/25/checkpoints
INFO:syne_tune.tuner:(trial 25) - scheduled config {'learning_rate': 0.8203370335228594, 'batch_size': 77, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.2960420911378594 --batch_size 104 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/26/checkpoints
INFO:syne_tune.tuner:(trial 26) - scheduled config {'learning_rate': 0.2960420911378594, 'batch_size': 104, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.2993874715754653 --batch_size 192 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/27/checkpoints
INFO:syne_tune.tuner:(trial 27) - scheduled config {'learning_rate': 0.2993874715754653, 'batch_size': 192, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.08056711961080017 --batch_size 36 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/28/checkpoints
INFO:syne_tune.tuner:(trial 28) - scheduled config {'learning_rate': 0.08056711961080017, 'batch_size': 36, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.26868380288030347 --batch_size 151 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/29/checkpoints
INFO:syne_tune.tuner:(trial 29) - scheduled config {'learning_rate': 0.26868380288030347, 'batch_size': 151, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 29 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.9197404791177789 --batch_size 66 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/30/checkpoints
INFO:syne_tune.tuner:(trial 30) - scheduled config {'learning_rate': 0.9197404791177789, 'batch_size': 66, 'max_epochs': 10}
INFO:syne_tune.stopping_criterion:reaching max wallclock time (720), stopping there.
INFO:syne_tune.tuner:Stopping trials that may still be running.
INFO:syne_tune.tuner:Tuning finished, results of trials can be found on /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046
--------------------
Resource summary (last result is reported):
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0    Stopped     4       0.100000         128          10      4          0.430578    29.093798
        1  Completed    10       0.446396         196          10     10          0.205652    72.747496
        2    Stopped     2       0.011548         254          10      2          0.900570    13.729115
        3    Stopped     8       0.149425         132          10      8          0.259171    58.980305
        4    Stopped     4       0.063172         242          10      4          0.900579    27.773950
        5  Completed    10       0.488018          41          10     10          0.140488   113.171314
        6    Stopped    10       0.590407         244          10     10          0.193776    70.364757
        7    Stopped     2       0.088129         148          10      2          0.899955    14.169738
        8    Stopped     2       0.012271         235          10      2          0.899840    13.434274
        9    Stopped     2       0.088457         236          10      2          0.899801    13.034437
       10    Stopped     4       0.082577          75          10      4          0.385970    35.426524
       11    Stopped     4       0.202352          65          10      4          0.543102    34.653495
       12    Stopped    10       0.335989          58          10     10          0.149558    90.924182
       13  Completed    10       0.789243          89          10     10          0.144887    77.365970
       14    Stopped     2       0.123379         176          10      2          0.899987    12.422906
       15    Stopped     2       0.137080         141          10      2          0.899983    13.395153
       16    Stopped     4       0.029140         116          10      4          0.900532    27.834111
       17    Stopped     2       0.033363         154          10      2          0.899996    13.407285
       18    Stopped     8       0.294430         210          10      8          0.241193    52.089688
       19    Stopped     2       0.102143         239          10      2          0.900002    12.487762
       20    Stopped     2       0.028463         115          10      2          0.899995    14.100359
       21    Stopped     2       0.037703          91          10      2          0.900026    14.664848
       22    Stopped     2       0.074104         192          10      2          0.901730    13.312770
       23    Stopped     2       0.303261         252          10      2          0.900009    12.725821
       24    Stopped     2       0.019823         252          10      2          0.899917    12.533380
       25    Stopped    10       0.820337          77          10     10          0.196842    81.816103
       26    Stopped    10       0.296042         104          10     10          0.198453    81.121330
       27    Stopped     4       0.299387         192          10      4          0.336183    24.610689
       28 InProgress     9       0.080567          36          10      9          0.203052   104.303746
       29  Completed    10       0.268684         151          10     10          0.222814    68.217289
       30 InProgress     1       0.919740          66          10      1          0.900037    10.070776
2 trials running, 29 finished (4 until the end), 723.70s wallclock-time

validation_error: best 0.1404876708984375 for trial-id 5
--------------------

 

Note that we are running a variant of ASHA where underperforming trials are stopped early. This is different to our implementation in Section 19.4.1, where each training job is started with a fixed max_epochs. In the latter case, a well-performing trial which reaches the full 10 epochs, first needs to train 1, then 2, then 4, then 8 epochs, each time starting from scratch. This type of pause-and-resume scheduling can be implemented efficiently by checkpointing the training state after each epoch, but we avoid this extra complexity here. After the experiment has finished, we can retrieve and plot results.

 

우리는 실적이 저조한 시험을 조기에 중단하는 ASHA 변형을 실행하고 있습니다. 이는 각 훈련 작업이 고정된 max_epochs로 시작되는 섹션 19.4.1의 구현과 다릅니다. 후자의 경우 전체 10개 에포크에 도달하는 잘 수행되는 시험은 처음부터 처음부터 시작할 때마다 먼저 1개, 2개, 4개, 8개 에포크를 훈련해야 합니다. 이러한 유형의 일시 중지 및 재개 스케줄링은 각 에포크 이후 훈련 상태를 검사하여 효율적으로 구현할 수 있지만 여기서는 이러한 추가적인 복잡성을 피합니다. 실험이 완료된 후 결과를 검색하고 플롯할 수 있습니다.

 

d2l.set_figsize()
e = load_experiment(tuner.name)
e.plot()

위의 코드는 실험 결과를 시각화하는 부분입니다.

  • d2l.set_figsize(): 그래프의 크기를 설정하는 함수입니다. 이 경우 그래프의 크기를 조정합니다.
  • e = load_experiment(tuner.name): load_experiment 함수를 사용하여 이전에 실행한 실험 결과를 로드합니다. tuner.name은 이전에 실행한 튜너의 이름을 나타냅니다.
  • e.plot(): 로드한 실험 결과를 시각화합니다. 이로써 실험 결과 그래프가 표시됩니다. 실험 결과에는 하이퍼파라미터 값에 대한 메트릭(metric)의 변화 추이와 관련된 정보가 포함됩니다.
WARNING:matplotlib.legend:No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.

 

19.5.3. Visualize the Optimization Process

Once more, we visualize the learning curves of every trial (each color in the plot represents a trial). Compare this to asynchronous random search in Section 19.3. As we have seen for successive halving in Section 19.4, most of the trials are stopped at 1 or 2 epochs (r min or η ∗ r min). However, trials do not stop at the same point, because they require different amount of time per epoch. If we ran standard successive halving instead of ASHA, we would need to synchronize our workers, before we can promote configurations to the next rung level.

 

다시 한 번 모든 시행의 학습 곡선을 시각화합니다(플롯의 각 색상은 시행을 나타냄). 이것을 섹션 19.3의 비동기 무작위 검색과 비교하십시오. 섹션 19.4에서 연속적인 반감기에 대해 살펴본 것처럼 대부분의 시행은 1 또는 2 에포크(r min 또는 θ * r min)에서 중단됩니다. 그러나 시도는 에포크마다 필요한 시간이 다르기 때문에 동일한 지점에서 멈추지 않습니다. ASHA 대신 표준 연속 절반을 실행한 경우 구성을 다음 단계 수준으로 승격하려면 먼저 작업자를 동기화해야 합니다.

 

d2l.set_figsize([6, 2.5])
results = e.results
for trial_id in results.trial_id.unique():
    df = results[results["trial_id"] == trial_id]
    d2l.plt.plot(
        df["st_tuner_time"],
        df["validation_error"],
        marker="o"
    )
d2l.plt.xlabel("wall-clock time")
d2l.plt.ylabel("objective function")

위의 코드는 실험 결과를 시각화하는 부분입니다.

  • d2l.set_figsize([6, 2.5]): 그래프의 크기를 설정하는 함수입니다. 이 경우 그래프의 가로 폭을 6로, 세로 높이를 2.5로 설정합니다.
  • results = e.results: 로드한 실험 결과에서 실제 결과 데이터를 가져옵니다.
  • for trial_id in results.trial_id.unique():: 실험 결과 중에서 고유한(trial_id가 다른) 각 실험에 대해서 반복합니다.
  • df = results[results["trial_id"] == trial_id]: 현재 반복 중인 trial_id에 해당하는 실험 결과 데이터를 선택합니다.
  • d2l.plt.plot(...): 선택한 실험 결과 데이터를 그래프로 표시합니다. x 축은 wall-clock time(실행 시간)을, y 축은 objective function(목적 함수) 값을 나타냅니다. marker="o"는 데이터 포인트를 원 형태로 표시하라는 옵션입니다.
  • d2l.plt.xlabel("wall-clock time"): x 축에 "wall-clock time" 레이블을 추가합니다.
  • d2l.plt.ylabel("objective function"): y 축에 "objective function" 레이블을 추가합니다.

이 코드는 실험 중 각 trial의 wall-clock time에 따른 objective function 값의 변화를 그래프로 표시하여 실험 결과를 시각적으로 확인할 수 있도록 합니다.

Text(0, 0.5, 'objective function')

19.5.4. Summary

 

Compared to random search, successive halving is not quite as trivial to run in an asynchronous distributed setting. To avoid synchronisation points, we promote configurations as quickly as possible to the next rung level, even if this means promoting some wrong ones. In practice, this usually does not hurt much, and the gains of asynchronous versus synchronous scheduling are usually much higher than the loss of the suboptimal decision making.

 

무작위 검색과 비교할 때, 연속적인 반감기는 비동기 분산 설정에서 실행하는 것이 그리 간단하지 않습니다. 동기화 지점을 피하기 위해 우리는 구성을 가능한 한 빨리 다음 단계 수준으로 승격합니다. 이는 잘못된 구성의 승격을 의미하더라도 마찬가지입니다. 실제로 이것은 일반적으로 큰 해를 끼치지 않으며 비동기식 스케줄링과 동기식 스케줄링의 이점은 일반적으로 차선책 의사 결정의 손실보다 훨씬 높습니다.

 

 

Asynchronous Successive Halving에 대해서 (GPT 3.5. 의 설명)

 

**비동기식 연속 하프링(Asynchronous Successive Halving)**은 하이퍼파라미터 최적화를 위한 고급 알고리즘 중 하나입니다. 이 방법은 Successive Halving 기술을 기반으로 하지만 병렬 처리와 비동기적 실행을 허용하여 계산 리소스를 효율적으로 활용합니다.

 

연속 하프링(Continuous Successive Halving) 또는 ASHA로도 알려진 이 방법은 다음과 같은 주요 아이디어를 포함합니다:

 

  1. 파라미터 세트는 다양한 하이퍼파라미터 구성을 나타냅니다. 초기에는 여러 구성이 생성됩니다.
  2. 리소스 할당: 초기에는 모든 파라미터 세트가 작은 리소스를 할당받아 빠르게 평가됩니다. 그런 다음 상위 성능을 보이는 세트가 더 많은 리소스를 할당받게 됩니다.
  3. 제거 및 확장: 하위 퍼포먼스를 보이는 파라미터 세트는 제거되고, 상위 퍼포먼스를 보이는 세트는 추가 리소스를 받아 성능을 더욱 정확하게 평가합니다. 이 과정을 반복하여 가장 우수한 하이퍼파라미터 세트를 찾습니다.
  4. 병렬 처리: ASHA는 파라미터 세트를 병렬로 처리하여 리소스 효율성을 극대화합니다. 이것은 다수의 하이퍼파라미터 구성을 동시에 평가하는 데 사용되며, 여러 프로세스 또는 워커(worker)가 동시에 실행됩니다.

 

비동기식 연속 하프링은 병렬 처리를 통해 하이퍼파라미터 최적화의 속도를 크게 높이며, 최적의 하이퍼파라미터 설정을 더욱 효율적으로 찾을 수 있도록 돕습니다. 이것은 계산 리소스를 최대한 활용하면서도 최상의 결과를 달성하기 위한 강력한 도구 중 하나입니다.

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/sh-intro.html

 

19.4. Multi-Fidelity Hyperparameter Optimization — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.4. Multi-Fidelity Hyperparameter Optimization

Training neural networks can be expensive even on moderate size datasets. Depending on the configuration space (Section 19.1.1.2), hyperparameter optimization requires tens to hundreds of function evaluations to find a well-performing hyperparameter configuration. As we have seen in Section 19.3, we can significantly speed up the overall wall-clock time of HPO by exploiting parallel resources, but this does not reduce the total amount of compute required.

 

적당한 크기의 데이터 세트에서도 신경망을 훈련하는 데 비용이 많이 들 수 있습니다. 구성 공간(19.1.1.2절)에 따라 하이퍼파라미터 최적화에는 성능이 좋은 하이퍼파라미터 구성을 찾기 위해 수십에서 수백 번의 함수 평가가 필요합니다. 섹션 19.3에서 살펴본 것처럼 병렬 리소스를 활용하여 HPO의 전체 벽시계 시간을 크게 단축할 수 있지만 이것이 필요한 총 컴퓨팅 양을 줄이지는 않습니다.

 

In this section, we will show how the evaluation of hyperparameter configurations can be sped up. Methods such as random search allocate the same amount of resources (e.g., number of epochs, training data points) to each hyperparameter evaluation. Fig. 19.4.1 depicts learning curves of a set of neural networks trained with different hyperparameter configurations. After a few epochs we are already able to visually distinguish between well-performing and suboptimal configurations. However, the learning curves are noisy, and we might still require the full amount of 100 epochs to identify the best performing one.

 

이 섹션에서는 하이퍼파라미터 구성의 평가 속도를 높이는 방법을 보여줍니다. 무작위 검색과 같은 방법은 각 하이퍼파라미터 평가에 동일한 양의 리소스(예: 시대 수, 교육 데이터 포인트)를 할당합니다. 그림 19.4.1은 다양한 하이퍼파라미터 구성으로 훈련된 신경망 세트의 학습 곡선을 보여줍니다. 몇 번의 시대가 지나면 이미 성능이 좋은 구성과 최적이 아닌 구성을 시각적으로 구분할 수 있습니다. 그러나 학습 곡선에는 잡음이 많으므로 최고의 성과를 내는 것을 식별하려면 여전히 100개의 에포크가 필요할 수 있습니다.

 

Fig. 19.4.1&nbsp; Learning curves of random hyperparameter configurations

 

Multi-fidelity hyperparameter optimization allocates more resources to promising configurations and stop evaluations of poorly performing ones early. This speeds up the optimization process, since we can try a larger number of configurations for the same total amount of resources.

 

다중 충실도 하이퍼파라미터 최적화는 유망한 구성에 더 많은 리소스를 할당하고 성능이 낮은 구성에 대한 평가를 조기에 중지합니다. 동일한 총 리소스 양에 대해 더 많은 수의 구성을 시도할 수 있으므로 최적화 프로세스 속도가 빨라집니다.

 

More formally, we expand our definition in Section 19.1.1, such that our objective function f(x,r) gets an additional input r∈[r min,r max], specifying the amount of resources that we are willing to spend for the evaluation of configuration x. We assume that the error f(x,r) decreases with r, whereas the computational cost c(x,r) increases. Typically, r represents the number of epochs for training the neural network, but it could also be the training subset size or the number of cross-validation folds.

 

보다 공식적으로, 목적 함수 f(x,r)가 추가 입력 r∈[r min,r max]를 얻도록 섹션 19.1.1의 정의를 확장하여 지출하려는 자원의 양을 지정합니다. 구성 x의 평가. 오류 f(x,r)는 r에 따라 감소하는 반면 계산 비용 c(x,r)은 증가한다고 가정합니다. 일반적으로 r은 신경망 훈련을 위한 에포크 수를 나타내지만 훈련 하위 집합 크기 또는 교차 검증 접기 수일 수도 있습니다.

 

from collections import defaultdict
import numpy as np
from scipy import stats
from d2l import torch as d2l

d2l.set_figsize()

위의 코드는 Python 라이브러리와 도구를 가져오고, 그림의 크기를 설정하는 부분입니다.

  1. from collections import defaultdict: Python의 내장 모듈인 collections에서 defaultdict 클래스를 가져옵니다. defaultdict는 기본값(default)을 가진 딕셔너리(dictionary)를 생성하는데 사용됩니다.
  2. import numpy as np: NumPy 라이브러리를 가져옵니다. NumPy는 과학적 계산을 위한 파이썬 라이브러리로 배열(array)과 행렬(matrix) 연산을 지원합니다. np는 NumPy를 짧게 참조하기 위한 별칭(alias)입니다.
  3. from scipy import stats: SciPy 라이브러리에서 stats 모듈을 가져옵니다. SciPy는 과학적 계산을 위한 다양한 기능을 제공하는 라이브러리로, 통계 분석과 관련된 함수와 도구를 포함하고 있습니다.
  4. from d2l import torch as d2l: "d2l" 라이브러리에서 "torch" 모듈을 가져오고, "d2l"을 짧게 참조하기 위한 별칭으로 사용합니다.
  5. d2l.set_figsize(): "d2l" 라이브러리에서 제공하는 함수인 set_figsize()를 호출하여 그림(플롯)의 크기를 설정합니다. 이 함수는 시각화에서 그림의 크기를 조정하는 데 사용됩니다. 크기를 따로 지정하지 않으면 기본 크기로 설정됩니다.

이 코드는 라이브러리를 가져와 사용할 수 있도록 하고, 그림의 크기를 설정하여 나중에 생성할 그래프나 플롯의 크기를 지정합니다.

 

Multi-Fidelity Hyperparameter Optimization이란? (GPT 3.5 답변)

 

**다중 신뢰도 하이퍼파라미터 최적화(Multi-Fidelity Hyperparameter Optimization)**는 하이퍼파라미터 최적화를 위한 고급 기술 중 하나로, 기계 학습 모델을 효율적으로 튜닝하기 위해 여러 가지 신뢰도 또는 리소스 수준에서 모델을 평가하는 방법입니다. 일반적으로 이러한 접근 방식은 계산 비용이 높은 고신뢰도(또는 고 리소스) 평가와 계산 비용이 낮은 저신뢰도(또는 저 리소스) 평가를 혼합하여 사용합니다.

 

다중 신뢰도 하이퍼파라미터 최적화의 핵심 아이디어는 다음과 같습니다.

 

  1. 고신뢰도 평가 (High-Fidelity Evaluation): 높은 신뢰도를 가진 평가는 모델의 성능을 정확하게 측정합니다. 이것은 많은 계산 리소스와 시간을 필요로 합니다. 예를 들어, 모든 훈련 데이터와 에포크 수를 늘리는 것과 같이 모델을 더 오랫동안 훈련하는 것이 포함될 수 있습니다.
  2. 저신뢰도 평가 (Low-Fidelity Evaluation): 저신뢰도 평가는 고신뢰도 평가보다 빠르게 수행됩니다. 예를 들어, 더 적은 훈련 데이터를 사용하거나 적은 에포크로 모델을 훈련하는 것이 이에 해당합니다.
  3. 리소스 관리: 다중 신뢰도 하이퍼파라미터 최적화는 제한된 계산 리소스 또는 시간 내에서 가장 효율적으로 최적화를 수행하려는 목표를 가지고 있습니다. 이를 위해 리소스를 고정된 신뢰도 평가와 저신뢰도 평가 사이에서 분배합니다.
  4. 바람직한 트레이드오프 탐색: 목표는 최적의 하이퍼파라미터 설정을 찾는 것이지만, 모든 경우에 고신뢰도 평가를 수행하는 것은 현실적이지 않을 수 있습니다. 따라서 가용한 리소스 내에서 가능한 한 많은 하이퍼파라미터 설정을 평가하여 최상의 트레이드오프를 찾습니다.
  5. 자동화된 하이퍼파라미터 선택: 다중 신뢰도 하이퍼파라미터 최적화는 주어진 리소스 내에서 자동으로 하이퍼파라미터를 선택하고 평가합니다. 이것은 기계 학습 엔지니어 또는 데이터 과학자에게 매우 유용합니다.

다중 신뢰도 하이퍼파라미터 최적화는 하이퍼파라미터 튜닝 과정을 가속화하고 계산 리소스를 효율적으로 활용하면서 최상의 하이퍼파라미터 설정을 찾는 데 도움을 줍니다. 이 방법은 기계 학습 모델의 성능을 최대화하는 데 중요합니다.

19.4.1. Successive Halving

One of the simplest ways to adapt random search to the multi-fidelity setting is successive halving (Jamieson and Talwalkar, 2016, Karnin et al., 2013). The basic idea is to start with N configurations, for example randomly sampled from the configuration space, and to train each of them for r min epochs only. We then discard a fraction of the worst performing trials and train the remaining ones for longer. Iterating this process, fewer trials run for longer, until at least one trial reaches r max epochs.

 

다중 충실도 설정에 무작위 검색을 적용하는 가장 간단한 방법 중 하나는 연속적인 반감기입니다(Jamieson and Talwalkar, 2016, Karnin et al., 2013). 기본 아이디어는 예를 들어 구성 공간에서 무작위로 샘플링된 N 구성으로 시작하고 각 구성을 r min epoch 동안만 훈련하는 것입니다. 그런 다음 성능이 가장 낮은 시험 중 일부를 버리고 나머지 시험을 더 오랫동안 훈련합니다. 이 프로세스를 반복하면 적어도 하나의 시도가 r 최대 에포크에 도달할 때까지 더 적은 수의 시도가 더 오랫동안 실행됩니다.

 

More formally, consider a minimum budget r min (for example 1 epoch), a maximum budget r max, for example max_epochs in our previous example, and a halving constant η∈{2,3,…}. For simplicity, assume that r max = r min η**k, with K∈ . The number of initial configurations is then N=η**k. Let us define the set of rungs R = {r min, r min η, r min η**2,…,r max}.

 

보다 공식적으로는 최소 예산 r min(예: 1 epoch), 최대 예산 r max(예: 이전 예의 max_epochs) 및 반감 상수 eta∈{2,3,…}를 고려합니다. 단순화를 위해 r max = r min θ**k, K∈ʼ 라고 가정합니다. 그러면 초기 구성 수는 N=θ**k입니다. 단계 세트 R = {r min, r min eta, r min eta**2,…,r max}를 정의해 보겠습니다.

 

One round of successive halving proceeds as follows. We start with running N trials until the first rung r min. Sorting the validation errors, we keep the top 1/η fraction (which amounts to η**k−1 configurations) and discard all the rest. The surviving trials are trained for the next rung (r min η epochs), and the process is repeated. At each rung, a 1/η fraction of trials survives and their training continues with a η times larger budget. With this particular choice of N, only a single trial will be trained to the full budget r max. Once such a round of successive halving is done, we start the next one with a new set of initial configurations, iterating until the total budget is spent.

 

한 라운드의 연속적인 반감기는 다음과 같이 진행됩니다. 첫 번째 rung r min까지 N번 시도를 실행하는 것으로 시작합니다. 검증 오류를 정렬하면서 상위 1/eta 부분(eta**k−1 구성에 해당)을 유지하고 나머지는 모두 삭제합니다. 살아남은 시도는 다음 단계(r min θ epochs)에 대해 훈련되고 프로세스가 반복됩니다. 각 단계에서 시행의 1/θ 비율이 살아남고 해당 훈련은 θ배 더 큰 예산으로 계속됩니다. 이 특정 N 선택을 사용하면 단일 시도만 전체 예산 r max로 학습됩니다. 이러한 연속적인 반감기가 완료되면 새로운 초기 구성 세트로 다음 단계를 시작하여 총 예산이 소비될 때까지 반복합니다.

 

Fig. 19.4.2&nbsp; Learning curves of random hyperparameter configurations.

 

Successive Halving 이란? (GPT 3.5 답변)

 

Successive Halving은 하이퍼파라미터 최적화에서 사용되는 고급 기술 중 하나입니다. 이 방법은 많은 하이퍼파라미터 구성을 효율적으로 평가하고 가장 우수한 하이퍼파라미터 구성을 찾는 데 도움을 줍니다.

 

Successive Halving은 다음 단계로 구성됩니다:

 

  1. 초기 라운드 (Initial Round): 먼저 모든 하이퍼파라미터 구성을 동일한 리소스 또는 시간 내에서 평가합니다. 이 단계에서는 많은 하이퍼파라미터 구성을 아직 유망한지 판단하지 않고 각각을 동등하게 다룹니다.
  2. 선택 (Selection): 초기 라운드에서 우수한 일부 하이퍼파라미터 구성만 선택합니다. 일반적으로 이것은 상위 N개 구성을 선택하는 것으로 시작합니다. 이 선택 기준은 주로 목표 지표 (예: 정확도 또는 손실)을 기반으로 합니다.
  3. 제거 (Elimination): 선택된 하이퍼파라미터 구성 중 일부를 제거합니다. 제거 기준은 각 구성의 상대적 효용성을 평가하는 데 사용됩니다. 이것은 효율성을 높이기 위한 주요 단계로, 낮은 성능을 보이는 하이퍼파라미터 구성을 제거하고 리소스를 더 높은 효과적인 평가로 할당하는 데 도움을 줍니다.
  4. 라운드 반복 (Iteration): 선정된 하이퍼파라미터 구성들을 다음 라운드로 이동시킵니다. 이제 리소스 또는 시간을 더욱 증가시켜 더 정확한 평가를 수행합니다. 이 프로세스는 몇 라운드에 걸쳐 반복됩니다.

Successive Halving은 초기에 무작위로 선택된 하이퍼파라미터 구성들을 점진적으로 걸러내고 가장 우수한 구성을 찾기 위해 리소스를 최적으로 활용하는 방법 중 하나입니다. 이 방법은 계산 리소스를 효율적으로 활용하면서도 최상의 하이퍼파라미터 설정을 찾는 데 도움을 줍니다.

 

We subclass the HPOScheduler base class from Section 19.2 in order to implement successive halving, allowing for a generic HPOSearcher object to sample configurations (which, in our example below, will be a RandomSearcher). Additionally, the user has to pass the minimum resource r min, the maximum resource r max and η as input. Inside our scheduler, we maintain a queue of configurations that still need to be evaluated for the current rung ri. We update the queue every time we jump to the next rung.

 

연속적인 절반 분할을 구현하기 위해 섹션 19.2에서 HPOScheduler 기본 클래스를 서브클래싱하여 일반 HPOSearcher 객체가 샘플 구성(아래 예에서는 RandomSearcher가 됨)을 허용합니다. 또한 사용자는 최소 리소스 r min, 최대 리소스 r max 및 eta를 입력으로 전달해야 합니다. 스케줄러 내에서는 현재 단계에 대해 여전히 평가해야 하는 구성 대기열을 유지 관리합니다. 다음 단계로 이동할 때마다 대기열을 업데이트합니다.

 

class SuccessiveHalvingScheduler(d2l.HPOScheduler):  #@save
    def __init__(self, searcher, eta, r_min, r_max, prefact=1):
        self.save_hyperparameters()
        # Compute K, which is later used to determine the number of configurations
        self.K = int(np.log(r_max / r_min) / np.log(eta))
        # Define the rungs
        self.rung_levels = [r_min * eta ** k for k in range(self.K + 1)]
        if r_max not in self.rung_levels:
            # The final rung should be r_max
            self.rung_levels.append(r_max)
            self.K += 1
        # Bookkeeping
        self.observed_error_at_rungs = defaultdict(list)
        self.all_observed_error_at_rungs = defaultdict(list)
        # Our processing queue
        self.queue = []

위의 코드는 SuccessiveHalvingScheduler라는 클래스를 정의하는 부분입니다. 이 클래스는 하이퍼파라미터 최적화 실험을 위한 스케줄러로 사용됩니다.

  1. def __init__(self, searcher, eta, r_min, r_max, prefact=1):: SuccessiveHalvingScheduler 클래스의 초기화 메서드입니다. 이 클래스는 여러 하이퍼파라미터를 받아 초기화됩니다.
    • searcher: 하이퍼파라미터 탐색기(searcher) 객체입니다.
    • eta: 탐색 단계 간의 이동 비율입니다.
    • r_min: 최소 리소스(예: 시간, 계산 능력)입니다.
    • r_max: 최대 리소스(예: 시간, 계산 능력)입니다.
    • prefact: 사전 요소(pre-factored)입니다.
  2. self.K = int(np.log(r_max / r_min) / np.log(eta)): K는 하이퍼파라미터 조합을 조사할 최대 횟수를 나타내는 변수입니다. eta와 리소스 범위에 따라 계산됩니다.
  3. self.rung_levels = [r_min * eta ** k for k in range(self.K + 1)]: rung_levels는 각 단계의 리소스 레벨을 저장하는 리스트입니다. r_min에서 시작하여 eta의 거듭제곱을 계산하여 각 단계의 리소스 레벨을 결정합니다.
  4. if r_max not in self.rung_levels:: r_max가 rung_levels에 포함되지 않으면, r_max를 추가합니다. 이렇게 하여 최종 단계에서도 r_max 리소스를 사용할 수 있도록 합니다.
  5. self.observed_error_at_rungs = defaultdict(list): observed_error_at_rungs는 각 단계에서 관찰된 에러를 저장하기 위한 딕셔너리입니다. 에러는 각 단계에서 계산되고 저장됩니다.
  6. self.all_observed_error_at_rungs = defaultdict(list): all_observed_error_at_rungs는 모든 실험에서 관찰된 에러를 저장하기 위한 딕셔너리입니다. 모든 실험에서 관찰된 에러를 추적합니다.
  7. self.queue = []: 실험을 수행하기 위한 큐(queue)를 초기화합니다. 실험 조합은 이 큐에 추가되어 순차적으로 실행됩니다.

이 클래스는 Successive Halving 알고리즘에 기반하여 하이퍼파라미터 탐색을 수행합니다. 각 단계에서 최적의 하이퍼파라미터 조합을 선택하고, 이를 기반으로 다음 단계의 실험을 수행합니다.

 

In the beginning our queue is empty, and we fill it with n=prefact⋅η**k configurations, which are first evaluated on the smallest rung r min. Here, prefact allows us to reuse our code in a different context. For the purpose of this section, we fix prefact=1. Every time resources become available and the HPOTuner object queries the suggest function, we return an element from the queue. Once we finish one round of successive halving, which means that we evaluated all surviving configurations on the highest resource level r max and our queue is empty, we start the entire process again with a new, randomly sampled set of configurations.

 

처음에는 대기열이 비어 있으며 n=prefact⋅eta**k 구성으로 채워져 가장 작은 단계 r min에서 먼저 평가됩니다. 여기서 prefact를 사용하면 다른 컨텍스트에서 코드를 재사용할 수 있습니다. 이 섹션의 목적을 위해 prefact=1을 수정합니다. 리소스를 사용할 수 있게 되고 HPOTuner 개체가 제안 기능을 쿼리할 때마다 대기열에서 요소를 반환합니다. 한 라운드의 연속적인 반감기를 마치면, 즉 가장 높은 리소스 수준 r max에서 살아남은 모든 구성을 평가하고 대기열이 비어 있으면 무작위로 샘플링된 새로운 구성 세트로 전체 프로세스를 다시 시작합니다.

 

@d2l.add_to_class(SuccessiveHalvingScheduler)  #@save
def suggest(self):
    if len(self.queue) == 0:
        # Start a new round of successive halving
        # Number of configurations for the first rung:
        n0 = int(self.prefact * self.eta ** self.K)
        for _ in range(n0):
            config = self.searcher.sample_configuration()
            config["max_epochs"] = self.r_min  # Set r = r_min
            self.queue.append(config)
    # Return an element from the queue
    return self.queue.pop()

위의 코드는 SuccessiveHalvingScheduler 클래스에 suggest 메서드를 추가하는 부분입니다. 이 메서드는 다음 실험에 사용할 하이퍼파라미터 조합을 제안하는 역할을 합니다.

  1. if len(self.queue) == 0:: 큐(queue)가 비어있는 경우, 새로운 Successive Halving 라운드를 시작합니다. 이는 다음 단계에서 실험할 하이퍼파라미터 조합을 선택하는 단계입니다.
  2. n0 = int(self.prefact * self.eta ** self.K): 첫 번째 단계의 실험 횟수(n0)를 계산합니다. prefact와 eta를 사용하여 최초 단계에서 실험할 하이퍼파라미터 조합의 수를 결정합니다.
  3. for _ in range(n0):: 계산된 실험 횟수만큼 반복하여 하이퍼파라미터 조합을 선택하고 큐에 추가합니다.
  4. config["max_epochs"] = self.r_min: 선택한 하이퍼파라미터 조합의 max_epochs 값을 r_min으로 설정합니다. 이렇게 하여 해당 단계에서의 최소 리소스를 사용하게 됩니다.
  5. self.queue.pop(): 큐에서 하이퍼파라미터 조합을 하나씩 꺼내서 반환합니다. 이 조합은 다음 실험에 사용됩니다.

이 메서드는 Successive Halving 알고리즘에 따라 다음 실험에 사용할 하이퍼파라미터 조합을 선택하고, 큐에서 해당 조합을 제거하는 역할을 합니다.

 

 

When we collected a new data point, we first update the searcher module. Afterwards we check if we already collect all data points on the current rung. If so, we sort all configurations and push the top 1/η configurations into the queue.

 

새로운 데이터 포인트를 수집하면 먼저 검색 모듈을 업데이트합니다. 그런 다음 현재 단계에서 모든 데이터 포인트를 이미 수집했는지 확인합니다. 그렇다면 모든 구성을 정렬하고 상위 1/eta 구성을 대기열에 푸시합니다.

 

@d2l.add_to_class(SuccessiveHalvingScheduler)  #@save
def update(self, config: dict, error: float, info=None):
    ri = int(config["max_epochs"])  # Rung r_i
    # Update our searcher, e.g if we use Bayesian optimization later
    self.searcher.update(config, error, additional_info=info)
    self.all_observed_error_at_rungs[ri].append((config, error))
    if ri < self.r_max:
        # Bookkeeping
        self.observed_error_at_rungs[ri].append((config, error))
        # Determine how many configurations should be evaluated on this rung
        ki = self.K - self.rung_levels.index(ri)
        ni = int(self.prefact * self.eta ** ki)
        # If we observed all configuration on this rung r_i, we estimate the
        # top 1 / eta configuration, add them to queue and promote them for
        # the next rung r_{i+1}
        if len(self.observed_error_at_rungs[ri]) >= ni:
            kiplus1 = ki - 1
            niplus1 = int(self.prefact * self.eta ** kiplus1)
            best_performing_configurations = self.get_top_n_configurations(
                rung_level=ri, n=niplus1
            )
            riplus1 = self.rung_levels[self.K - kiplus1]  # r_{i+1}
            # Queue may not be empty: insert new entries at the beginning
            self.queue = [
                dict(config, max_epochs=riplus1)
                for config in best_performing_configurations
            ] + self.queue
            self.observed_error_at_rungs[ri] = []  # Reset

위의 코드는 SuccessiveHalvingScheduler 클래스에 update 메서드를 추가하는 부분입니다. 이 메서드는 각 실험의 결과를 기반으로 다음 단계의 실험을 업데이트하고 관리합니다.

  1. ri = int(config["max_epochs"]): 현재 실험에서 사용한 max_epochs 값을 가져와 ri 변수에 저장합니다. 이 값은 현재 실험의 리소스 레벨을 나타냅니다.
  2. self.searcher.update(config, error, additional_info=info): searcher 객체를 업데이트합니다. 이는 나중에 베이지안 최적화와 같은 다른 탐색 알고리즘을 사용할 때 유용합니다.
  3. self.all_observed_error_at_rungs[ri].append((config, error)): 모든 실험에서 현재 리소스 레벨 ri에서 관찰된 에러를 저장합니다.
  4. if ri < self.r_max:: 현재 리소스 레벨이 최대 리소스 레벨 r_max보다 작은 경우에만 다음 단계의 처리를 진행합니다.
  5. ki = self.K - self.rung_levels.index(ri): 현재 리소스 레벨에 해당하는 단계 ki를 계산합니다.
  6. ni = int(self.prefact * self.eta ** ki): 현재 단계에서 평가할 실험의 수를 계산합니다.
  7. if len(self.observed_error_at_rungs[ri]) >= ni:: 현재 리소스 레벨에서 이미 모든 실험을 수행한 경우에는 다음 단계로 넘어갑니다.
  8. kiplus1 = ki - 1과 niplus1 = int(self.prefact * self.eta ** kiplus1)을 계산하여 다음 단계에서 평가할 실험의 수와 단계를 결정합니다.
  9. best_performing_configurations = self.get_top_n_configurations(rung_level=ri, n=niplus1): 현재 단계에서 성능이 가장 좋은 상위 niplus1개의 하이퍼파라미터 조합을 가져옵니다.
  10. riplus1 = self.rung_levels[self.K - kiplus1]: 다음 단계의 리소스 레벨 riplus1을 결정합니다.
  11. self.queue = [...] + self.queue: 다음 단계의 실험을 큐에 추가합니다. 이때, 현재 큐에 있는 실험들은 다음 단계의 리소스 레벨로 업데이트되고, 상위 성능 조합들이 추가됩니다.
  12. self.observed_error_at_rungs[ri] = []: 현재 단계에서 관찰된 에러를 리셋하여 다음 단계를 위한 준비를 합니다.

이 메서드는 Successive Halving 알고리즘의 핵심 로직을 구현하며, 각 실험의 결과를 바탕으로 다음 실험의 하이퍼파라미터 조합을 선택하고 큐를 관리합니다.

 

 

Configurations are sorted based on their observed performance on the current rung. 

구성은 현재 단계에서 관찰된 성능을 기준으로 정렬됩니다.

 

@d2l.add_to_class(SuccessiveHalvingScheduler)  #@save
def get_top_n_configurations(self, rung_level, n):
    rung = self.observed_error_at_rungs[rung_level]
    if not rung:
        return []
    sorted_rung = sorted(rung, key=lambda x: x[1])
    return [x[0] for x in sorted_rung[:n]]

위의 코드는 SuccessiveHalvingScheduler 클래스에 get_top_n_configurations 메서드를 추가하는 부분입니다. 이 메서드는 주어진 리소스 레벨에서 성능이 가장 좋은 상위 n개 하이퍼파라미터 조합을 반환합니다.

  1. rung = self.observed_error_at_rungs[rung_level]: 주어진 리소스 레벨 rung_level에서 관찰된 모든 실험 결과를 가져옵니다.
  2. if not rung:: 만약 해당 리소스 레벨에서 아직 어떤 실험이 수행되지 않았다면 빈 리스트를 반환합니다.
  3. sorted_rung = sorted(rung, key=lambda x: x[1]): 실험 결과를 성능(에러 값)에 따라 정렬합니다.
  4. return [x[0] for x in sorted_rung[:n]]: 상위 n개의 실험 중 하이퍼파라미터 조합만을 반환합니다. 이는 다음 단계의 실험에 사용됩니다.

즉, get_top_n_configurations 메서드는 주어진 리소스 레벨에서 성능이 가장 좋은 하이퍼파라미터 조합을 선택하는데 사용되며, Successive Halving 알고리즘의 핵심 부분 중 하나입니다.

 

Let us see how successive halving is doing on our neural network example. We will use r min=2, η=2, r max=10, so that rung levels are 2,4,8,10.

 

신경망 예제에서 연속적인 반감기가 어떻게 수행되는지 살펴보겠습니다. r min=2, eta=2, r max=10을 사용하므로 단계 수준은 2,4,8,10이 됩니다.

 

min_number_of_epochs = 2
max_number_of_epochs = 10
eta = 2
num_gpus=1

config_space = {
    "learning_rate": stats.loguniform(1e-2, 1),
    "batch_size": stats.randint(32, 256),
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 Successive Halving HPO (Hyperparameter Optimization) 알고리즘을 설정하는 부분입니다. 이 알고리즘은 하이퍼파라미터 최적화를 위해 사용되며, 주어진 리소스로 가장 좋은 하이퍼파라미터 설정을 찾는 데 도움이 됩니다. 아래는 각 설정과 변수에 대한 설명입니다.

  • min_number_of_epochs (최소 에포크 수): 각 실험에서 최소 몇 번의 에포크를 실행할지를 나타냅니다. 이 값은 2로 설정되어 있습니다.
  • max_number_of_epochs (최대 에포크 수): 각 실험에서 최대 몇 번의 에포크까지 실행할지를 나타냅니다. 이 값은 10으로 설정되어 있습니다.
  • eta (탐색 요인): Successive Halving 알고리즘에서 리소스를 나누는 데 사용되는 요인을 나타냅니다. 이 값은 2로 설정되어 있으며, 리소스가 반으로 줄어들 때마다 실행되는 실험 수가 2배로 증가합니다.
  • num_gpus (GPU 수): 사용 가능한 GPU 수를 나타냅니다. 이 예제에서는 1로 설정되어 있습니다.
  • config_space (하이퍼파라미터 공간): 하이퍼파라미터 최적화를 위해 탐색할 하이퍼파라미터 공간을 정의합니다. 여기에서는 학습률(learning_rate)과 배치 크기(batch_size)를 설정하고, 각각 loguniform 및 randint 확률 분포를 사용하여 하이퍼파라미터를 탐색할 범위를 지정합니다.
  • initial_config (초기 하이퍼파라미터 설정): 최초의 실험을 위해 사용되는 초기 하이퍼파라미터 설정을 나타냅니다. 이 예제에서는 학습률을 0.1로, 배치 크기를 128로 설정합니다.

이러한 설정과 변수들은 Successive Halving HPO 알고리즘을 실행하고 하이퍼파라미터 최적화를 수행하는 데 필요한 매개변수와 공간을 정의합니다.

 

We just replace the scheduler with our new SuccessiveHalvingScheduler.

 

스케줄러를 새로운 SuccessiveHalvingScheduler로 교체합니다.

 

searcher = d2l.RandomSearcher(config_space, initial_config=initial_config)
scheduler = SuccessiveHalvingScheduler(
    searcher=searcher,
    eta=eta,
    r_min=min_number_of_epochs,
    r_max=max_number_of_epochs,
)
tuner = d2l.HPOTuner(
    scheduler=scheduler,
    objective=d2l.hpo_objective_lenet,
)
tuner.run(number_of_trials=30)

위의 코드는 Successive Halving HPO 알고리즘을 구현하고 실행하는 부분입니다. 아래는 코드의 주요 내용에 대한 설명입니다.

  • searcher: RandomSearcher는 하이퍼파라미터 탐색을 수행하는 데 사용되는 탐색자(searcher)입니다. config_space에서 정의한 하이퍼파라미터 공간을 기반으로 하이퍼파라미터 설정을 무작위로 추출하며, 초기 설정은 initial_config로 설정됩니다.
  • scheduler: SuccessiveHalvingScheduler는 Successive Halving 알고리즘의 스케줄러입니다. 이 스케줄러는 searcher로부터 샘플된 하이퍼파라미터 설정을 기반으로 실험을 관리하고, eta, r_min, r_max 등을 사용하여 실험을 반복하고 스케줄링합니다.
  • tuner: HPOTuner는 하이퍼파라미터 최적화를 수행하는 클래스입니다. scheduler를 통해 실험을 관리하고, objective 함수를 사용하여 각 실험의 성능을 평가하며, number_of_trials 매개변수에 지정된 횟수만큼 실험을 실행합니다.

이렇게 구성된 코드는 Successive Halving 알고리즘을 사용하여 하이퍼파라미터 최적화를 수행하며, 30회의 실험을 실행하여 최적의 하이퍼파라미터 설정을 찾습니다.

 error = 0.17762434482574463, runtime = 53.576584339141846

We can visualize the learning curves of all configurations that we evaluated. Most of the configurations are stopped early and only the better performing configurations survive until r max. Compare this to vanilla random search, which would allocate r max to every configuration.

 

평가한 모든 구성의 학습 곡선을 시각화할 수 있습니다. 대부분의 구성은 조기에 중지되며 더 나은 성능의 구성만 r max까지 유지됩니다. 이것을 모든 구성에 r max를 할당하는 바닐라 무작위 검색과 비교해 보세요.

 

for rung_index, rung in scheduler.all_observed_error_at_rungs.items():
    errors = [xi[1] for xi in rung]
    d2l.plt.scatter([rung_index] * len(errors), errors)
d2l.plt.xlim(min_number_of_epochs - 0.5, max_number_of_epochs + 0.5)
d2l.plt.xticks(
    np.arange(min_number_of_epochs, max_number_of_epochs + 1),
    np.arange(min_number_of_epochs, max_number_of_epochs + 1)
)
d2l.plt.ylabel("validation error")
d2l.plt.xlabel("epochs")

위의 코드는 Successive Halving HPO 알고리즘을 통해 각 rung(레벨)에서 관찰된 검증 오차(validation error)를 시각화하는 부분입니다. 아래는 코드의 주요 내용에 대한 설명입니다.

  • for rung_index, rung in scheduler.all_observed_error_at_rungs.items():: all_observed_error_at_rungs에는 각 rung 레벨에서 관찰된 검증 오차의 정보가 저장되어 있습니다. 이 코드는 각 rung에 대한 정보를 반복하며 그래프를 그립니다.
  • errors = [xi[1] for xi in rung]: 각 rung에서 관찰된 검증 오차를 추출하여 errors 리스트에 저장합니다.
  • d2l.plt.scatter([rung_index] * len(errors), errors): rung 레벨에 해당하는 x 좌표에 해당 오차 값을 점으로 표시하여 그래프에 추가합니다.
  • d2l.plt.xlim(min_number_of_epochs - 0.5, max_number_of_epochs + 0.5): x 축의 범위를 설정합니다.
  • d2l.plt.xticks(np.arange(min_number_of_epochs, max_number_of_epochs + 1), np.arange(min_number_of_epochs, max_number_of_epochs + 1)): x 축의 눈금을 설정합니다. rung 레벨에 해당하는 값들이 표시됩니다.
  • d2l.plt.ylabel("validation error")와 d2l.plt.xlabel("epochs"): y 축과 x 축에 라벨을 추가합니다.

이 코드를 통해 각 rung 레벨에서 관찰된 검증 오차를 epochs(에폭)별로 시각적으로 확인할 수 있습니다.

Text(0.5, 0, 'epochs')

Finally, note some slight complexity in our implementation of SuccessiveHalvingScheduler. Say that a worker is free to run a job, and suggest is called when the current rung has almost been completely filled, but another worker is still busy with an evaluation. Since we lack the metric value from this worker, we cannot determine the top 1/η fraction to open up the next rung. On the other hand, we want to assign a job to our free worker, so it does not remain idle. Our solution is to start a new round of successive halving and assign our worker to the first trial there. However, once a rung is completed in update, we make sure to insert new configurations at the beginning of the queue, so they take precedence over configurations from the next round.

 

마지막으로 SuccessiveHalvingScheduler 구현이 약간 복잡하다는 점에 유의하세요. 작업자가 작업을 자유롭게 실행할 수 있고 현재 단계가 거의 완전히 채워졌을 때 제안이 호출되지만 다른 작업자는 여전히 평가로 바쁘다고 가정해 보겠습니다. 이 작업자의 메트릭 값이 부족하기 때문에 다음 단계를 열기 위한 상위 1/θ 비율을 결정할 수 없습니다. 반면에 우리는 무료 작업자에게 작업을 할당하여 유휴 상태로 남아 있지 않도록 하려고 합니다. 우리의 해결책은 새로운 연속 반감기 라운드를 시작하고 그곳에서 첫 번째 시도에 작업자를 할당하는 것입니다. 그러나 업데이트에서 단계가 완료되면 대기열 시작 부분에 새 구성을 삽입하여 다음 라운드의 구성보다 우선하도록 합니다.

 

19.4.2. Summary

In this section, we introduced the concept of multi-fidelity hyperparameter optimization, where we assume to have access to cheap-to-evaluate approximations of the objective function, such as validation error after a certain number of epochs of training as proxy to validation error after the full number of epochs. Multi-fidelity hyperparameter optimization allows to reduce the overall computation of the HPO instead of just reducing the wall-clock time.

 

이 섹션에서는 다중 충실도 하이퍼파라미터 최적화의 개념을 소개했습니다. 여기서 우리는 검증 오류에 대한 프록시로서 특정 횟수의 훈련 후 검증 오류와 같이 목적 함수의 평가하기 쉬운 근사값에 액세스할 수 있다고 가정합니다. 전체 에포크 수 이후. 다중 충실도 하이퍼파라미터 최적화를 사용하면 벽시계 시간을 줄이는 대신 HPO의 전체 계산을 줄일 수 있습니다.

 

We implemented and evaluated successive halving, a simple yet efficient multi-fidelity HPO algorithm.

 

우리는 간단하면서도 효율적인 다중 충실도 HPO 알고리즘인 연속 반감기를 구현하고 평가했습니다.

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/rs-async.html

 

19.3. Asynchronous Random Search — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.3. Asynchronous Random Search

 

As we have seen in the previous Section 19.2, we might have to wait hours or even days before random search returns a good hyperparameter configuration, because of the expensive evaluation of hyperparameter configurations. In practice, we have often access to a pool of resources such as multiple GPUs on the same machine or multiple machines with a single GPU. This begs the question: How do we efficiently distribute random search?

 

이전 섹션 19.2에서 살펴본 것처럼 하이퍼파라미터 구성에 대한 평가 비용이 많이 들기 때문에 무작위 검색이 좋은 하이퍼파라미터 구성을 반환하기까지 몇 시간 또는 심지어 며칠을 기다려야 할 수도 있습니다. 실제로 우리는 동일한 시스템의 여러 GPU 또는 단일 GPU가 있는 여러 시스템과 같은 리소스 풀에 액세스하는 경우가 많습니다. 이는 다음과 같은 질문을 던집니다. 무작위 검색을 어떻게 효율적으로 배포할 수 있습니까?

 

In general, we distinguish between synchronous and asynchronous parallel hyperparameter optimization (see Fig. 19.3.1). In the synchronous setting, we wait for all concurrently running trials to finish, before we start the next batch. Consider configuration spaces that contain hyperparameters such as the number of filters or number of layers of a deep neural network. Hyperparameter configurations that contain a larger number of layers of filters will naturally take more time to finish, and all other trials in the same batch will have to wait at synchronisation points (grey area in Fig. 19.3.1) before we can continue the optimization process.

 

일반적으로 우리는 동기식 병렬 하이퍼파라미터 최적화와 비동기식 병렬 하이퍼파라미터 최적화를 구별합니다(그림 19.3.1 참조). 동기 설정에서는 다음 배치를 시작하기 전에 동시에 실행 중인 모든 시도가 완료될 때까지 기다립니다. 심층 신경망의 필터 수나 레이어 수와 같은 하이퍼파라미터가 포함된 구성 공간을 고려하세요. 더 많은 수의 필터 레이어를 포함하는 하이퍼파라미터 구성은 당연히 완료하는 데 더 많은 시간이 걸립니다. 그리고 동일한 배치의 다른 모든 시도는 최적화 프로세스를 계속하기 전에 동기화 지점(그림 19.3.1의 회색 영역)에서 기다려야 합니다.

 

In the asynchronous setting we immediately schedule a new trial as soon as resources become available. This will optimally exploit our resources, since we can avoid any synchronisation overhead. For random search, each new hyperparameter configuration is chosen independently of all others, and in particular without exploiting observations from any prior evaluation. This means we can trivially parallelize random search asynchronously. This is not straight-forward with more sophisticated methods that make decision based on previous observations (see Section 19.5). While we need access to more resources than in the sequential setting, asynchronous random search exhibits a linear speed-up, in that a certain performance is reached K times faster if K trials can be run in parallel.

 

비동기식 설정에서는 리소스를 사용할 수 있게 되는 즉시 새로운 평가판을 예약합니다. 동기화 오버헤드를 피할 수 있으므로 리소스를 최적으로 활용하게 됩니다. 무작위 검색의 경우 각각의 새로운 하이퍼파라미터 구성은 다른 모든 구성과 독립적으로 선택되며, 특히 이전 평가에서 관찰한 내용을 활용하지 않습니다. 이는 무작위 검색을 비동기적으로 간단하게 병렬화할 수 있음을 의미합니다. 이는 이전 관찰을 기반으로 결정을 내리는 보다 정교한 방법으로는 간단하지 않습니다(19.5절 참조). 순차 설정보다 더 많은 리소스에 액세스해야 하지만 비동기 무작위 검색은 K번 시도를 병렬로 실행할 수 있으면 특정 성능에 K배 더 빠르게 도달한다는 점에서 선형적인 속도 향상을 나타냅니다.

 

Fig. 19.3.1&nbsp; Distributing the hyperparameter optimization process either synchronously or asynchronously. Compared to the sequential setting, we can reduce the overall wall-clock time while keep the total compute constant. Synchronous scheduling might lead to idling workers in the case of stragglers.&nbsp;그림 19.3.1 하이퍼파라미터 최적화 프로세스를 동기식 또는 비동기식으로 배포합니다. 순차 설정에 비해 총 계산을 일정하게 유지하면서 전체 벽시계 시간을 줄일 수 있습니다. 동기식 일정은 낙오자의 경우 유휴 작업자로 이어질 수 있습니다.

 

In this notebook, we will look at asynchronous random search that, where trials are executed in multiple python processes on the same machine. Distributed job scheduling and execution is difficult to implement from scratch. We will use Syne Tune (Salinas et al., 2022), which provides us with a simple interface for asynchronous HPO. Syne Tune is designed to be run with different execution back-ends, and the interested reader is invited to study its simple APIs in order to learn more about distributed HPO.

 

이 노트북에서는 동일한 머신의 여러 Python 프로세스에서 시도가 실행되는 비동기 무작위 검색을 살펴보겠습니다. 분산 작업 스케줄링 및 실행은 처음부터 구현하기 어렵습니다. 비동기식 HPO를 위한 간단한 인터페이스를 제공하는 Syne Tune(Salinas et al., 2022)을 사용하겠습니다. Syne Tune은 다양한 실행 백엔드와 함께 실행되도록 설계되었으며 관심 있는 독자는 분산형 HPO에 대해 자세히 알아보기 위해 간단한 API를 연구하도록 초대됩니다.

 

import logging
from d2l import torch as d2l

logging.basicConfig(level=logging.INFO)
from syne_tune import StoppingCriterion, Tuner
from syne_tune.backend.python_backend import PythonBackend
from syne_tune.config_space import loguniform, randint
from syne_tune.experiments import load_experiment
from syne_tune.optimizer.baselines import RandomSearch

위의 코드는 하이퍼파라미터 최적화를 위한 도구와 라이브러리를 가져오고 초기 설정을 수행하는 부분입니다. 코드의 주요 내용은 다음과 같습니다:

  1. import logging: 로그 메시지를 기록하기 위한 로깅 모듈을 가져옵니다.
  2. from d2l import torch as d2l: "d2l" 패키지에서 PyTorch 관련 기능을 가져옵니다. 이 패키지는 Deep Learning for Dummies(이해를 돕기 위한 딥 러닝)에서 사용되는 유틸리티 함수와 도구를 제공합니다.
  3. logging.basicConfig(level=logging.INFO): 로깅 레벨을 설정하고 로깅을 초기화합니다. 이 코드는 INFO 레벨 이상의 로그 메시지를 표시하도록 설정합니다.
  4. from syne_tune import StoppingCriterion, Tuner: "syne_tune" 라이브러리에서 하이퍼파라미터 튜닝에 필요한 클래스인 StoppingCriterion과 Tuner를 가져옵니다.
  5. from syne_tune.backend.python_backend import PythonBackend: "syne_tune" 라이브러리에서 하이퍼파라미터 튜닝에 사용되는 백엔드(backend)인 PythonBackend를 가져옵니다.
  6. from syne_tune.config_space import loguniform, randint: 하이퍼파라미터 탐색 공간을 정의하기 위해 "syne_tune" 라이브러리에서 loguniform과 randint 함수를 가져옵니다. 이 함수들을 사용하여 하이퍼파라미터의 분포를 정의할 수 있습니다.
  7. from syne_tune.experiments import load_experiment: 하이퍼파라미터 튜닝 실험을 로드하는 데 사용되는 load_experiment 함수를 가져옵니다.
  8. from syne_tune.optimizer.baselines import RandomSearch: 랜덤 서치 기반의 최적화 알고리즘인 RandomSearch를 가져옵니다.

이 코드는 하이퍼파라미터 튜닝을 위한 다양한 도구와 라이브러리를 가져와 초기 설정을 수행하며, 이후의 코드에서 하이퍼파라미터 튜닝 실험을 진행할 준비를 마칩니다.

INFO:root:SageMakerBackend is not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
INFO:root:Ray Tune schedulers and searchers are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[raytune]'
or (for everything)
   pip install 'syne-tune[extra]'

 

19.3.1. Objective Function

First, we have to define a new objective function such that it now returns the performance back to Syne Tune via the report callback.

 

먼저, 보고서 콜백을 통해 성능을 Syne Tune으로 다시 반환하도록 새로운 목적 함수를 정의해야 합니다.

 

def hpo_objective_lenet_synetune(learning_rate, batch_size, max_epochs):
    from syne_tune import Reporter
    from d2l import torch as d2l

    model = d2l.LeNet(lr=learning_rate, num_classes=10)
    trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1)
    data = d2l.FashionMNIST(batch_size=batch_size)
    model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)
    report = Reporter()
    for epoch in range(1, max_epochs + 1):
        if epoch == 1:
            # Initialize the state of Trainer
            trainer.fit(model=model, data=data)
        else:
            trainer.fit_epoch()
        validation_error = trainer.validation_error().cpu().detach().numpy()
        report(epoch=epoch, validation_error=float(validation_error))

위의 코드는 하이퍼파라미터 최적화 실험을 위한 목표 함수인 hpo_objective_lenet_synetune를 정의하는 부분입니다. 이 함수는 SyneTune 라이브러리를 사용하여 하이퍼파라미터 튜닝을 수행하는데 필요한 내용을 포함하고 있습니다. 코드의 주요 내용은 다음과 같습니다:

  1. from syne_tune import Reporter: SyneTune 라이브러리에서 Reporter 클래스를 가져옵니다. Reporter는 실험 결과를 기록하고 보고하는 데 사용됩니다.
  2. model = d2l.LeNet(lr=learning_rate, num_classes=10): LeNet 아키텍처를 사용하여 모델을 생성합니다. 이때 학습률(learning_rate)은 인자로 전달된 값으로 설정됩니다.
  3. trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1): 하이퍼파라미터 최적화 트레이너인 HPOTrainer를 생성합니다. max_epochs와 num_gpus는 인자로 전달된 값으로 설정됩니다.
  4. data = d2l.FashionMNIST(batch_size=batch_size): Fashion MNIST 데이터셋을 사용하여 데이터를 로드합니다. 미니배치 크기(batch_size)는 인자로 전달된 값으로 설정됩니다.
  5. model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn): 모델의 초기화를 수행합니다. 초기화에 필요한 데이터를 제공하고, CNN 모델을 초기화하는 함수인 d2l.init_cnn을 사용합니다.
  6. report = Reporter(): 실험 결과를 기록하기 위해 Reporter 객체를 생성합니다.
  7. for epoch in range(1, max_epochs + 1):: 주어진 에폭 수(max_epochs)에 대한 반복문을 시작합니다.
  8. if epoch == 1:: 첫 번째 에폭에서는 트레이너의 초기 상태를 초기화합니다.
  9. trainer.fit(model=model, data=data): 트레이너를 사용하여 모델을 학습합니다.
  10. else:: 첫 번째 에폭 이후에는 trainer.fit_epoch()를 호출하여 추가 에폭을 학습합니다.
  11. validation_error = trainer.validation_error().cpu().detach().numpy(): 검증 오차를 계산하고 numpy 배열로 변환하여 저장합니다.
  12. report(epoch=epoch, validation_error=float(validation_error)): 현재 에폭과 검증 오차를 Reporter에 보고합니다.

이러한 과정을 통해 hpo_objective_lenet_synetune 함수는 하이퍼파라미터 최적화 실험을 수행하고, 각 에폭에서의 검증 오차를 기록하여 SyneTune 라이브러리와 함께 사용할 수 있도록 준비합니다.

 

Note that the PythonBackend of Syne Tune requires dependencies to be imported inside the function definition.

 

Syne Tune의 PythonBackend를 사용하려면 함수 정의 내로 종속성을 가져와야 합니다.

 

19.3.2. Asynchronous Scheduler

 

First, we define the number of workers that evaluate trials concurrently. We also need to specify how long we want to run random search, by defining an upper limit on the total wall-clock time.

 

먼저, 동시에 시험을 평가하는 작업자 수를 정의합니다. 또한 총 벽시계 시간의 상한을 정의하여 무작위 검색을 실행할 기간을 지정해야 합니다.

 

n_workers = 2  # Needs to be <= the number of available GPUs

max_wallclock_time = 12 * 60  # 12 minutes

위의 코드는 하이퍼파라미터 최적화 실험에 대한 몇 가지 설정을 지정하는 부분입니다.

  1. n_workers = 2: 병렬로 실행되는 작업자(worker)의 수를 나타냅니다. 이 값은 사용 가능한 GPU 수보다 작거나 같아야 합니다. 즉, 최대로 사용할 GPU 수를 지정합니다. 이 예에서는 2개의 GPU를 사용하도록 설정되어 있습니다.
  2. max_wallclock_time = 12 * 60: 최대 실행 시간을 분 단위로 나타냅니다. 즉, 실험의 최대 실행 시간을 12분으로 설정하고 있습니다. 이 값은 실험을 제한하는 데 사용될 수 있으며, 지정된 시간 내에 실험이 완료되어야 합니다. 실험에 따라 실행 시간이 다를 수 있으므로 적절한 값으로 설정해야 합니다. 이 예에서는 12분으로 설정되어 있으므로 실험이 12분 이내에 완료되어야 합니다.

 

Next, we state which metric we want to optimize and whether we want to minimize or maximize this metric. Namely, metric needs to correspond to the argument name passed to the report callback.

 

다음으로, 최적화할 측정항목과 이 측정항목을 최소화할지 최대화할지 여부를 명시합니다. 즉, 측정항목은 보고서 콜백에 전달된 인수 이름과 일치해야 합니다.

 

mode = "min"
metric = "validation_error"

위의 코드는 하이퍼파라미터 튜닝 실험에서 사용되는 최적화 모드와 평가 지표를 설정하는 부분입니다.

  1. mode = "min": 최적화 모드를 나타내는 변수입니다. "min"으로 설정되어 있으므로 최적화 과정에서는 평가 지표(metric)를 최소화하는 방향으로 진행됩니다. 다시 말해, 모델의 성능을 향상시키는 방향으로 하이퍼파라미터가 조절될 것입니다. 이는 일반적으로 검증 오차나 손실 함수를 최소화하는 경우에 사용됩니다.
  2. metric = "validation_error": 평가 지표를 나타내는 변수입니다. 이 변수는 최적화 모드에 따라 설정되며, 실험 중에 평가되는 지표를 나타냅니다. 이 경우 "validation_error"로 설정되어 있으므로 검증 오차를 평가 지표로 사용하여 최적화를 수행할 것입니다. 검증 오차를 최소화하도록 하이퍼파라미터를 조절하는 것이 목표입니다.

이러한 설정은 하이퍼파라미터 튜닝 실험의 목표와 방향성을 결정하는 중요한 요소 중 하나입니다.

 

We use the configuration space from our previous example. In Syne Tune, this dictionary can also be used to pass constant attributes to the training script. We make use of this feature in order to pass max_epochs. Moreover, we specify the first configuration to be evaluated in initial_config.

 

이전 예제의 구성 공간을 사용합니다. Syne Tune에서 이 사전을 사용하여 상수 속성을 교육 스크립트에 전달할 수도 있습니다. max_epochs를 전달하기 위해 이 기능을 사용합니다. 또한,initial_config에서 평가할 첫 번째 구성을 지정합니다.

 

config_space = {
    "learning_rate": loguniform(1e-2, 1),
    "batch_size": randint(32, 256),
    "max_epochs": 10,
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 하이퍼파라미터 튜닝 실험을 위한 하이퍼파라미터 공간과 초기 설정을 정의하는 부분입니다.

  1. config_space: 하이퍼파라미터 탐색 공간을 나타내는 딕셔너리입니다. 이 공간에는 다양한 하이퍼파라미터의 범위나 분포를 정의할 수 있습니다. 여기서 정의된 하이퍼파라미터는 다음과 같습니다:
    • "learning_rate": 학습률(learning rate)을 나타냅니다. loguniform(1e-2, 1)은 0.01에서 1 사이의 로그 균등 분포를 가진 값을 의미합니다.
    • "batch_size": 미니배치 크기(batch size)를 나타냅니다. randint(32, 256)은 32에서 256 사이의 정수 값을 나타냅니다.
    • "max_epochs": 최대 에폭 수를 나타냅니다. 여기서는 고정값으로 10으로 설정되어 있습니다.
  2. initial_config: 초기 하이퍼파라미터 설정을 나타내는 딕셔너리입니다. 실험의 초기 단계에서 사용할 하이퍼파라미터 설정을 정의합니다. 이 설정은 실험의 초기값으로 사용됩니다. 여기서는 다음과 같은 하이퍼파라미터 설정을 가지고 있습니다:
    • "learning_rate": 초기 학습률을 0.1로 설정합니다.
    • "batch_size": 초기 미니배치 크기를 128로 설정합니다.

이렇게 정의된 하이퍼파라미터 공간과 초기 설정은 하이퍼파라미터 튜닝 실험을 수행할 때 사용됩니다. 실험은 이 하이퍼파라미터 공간에서 하이퍼파라미터를 샘플링하고, 초기 설정을 시작점으로 하여 최적의 하이퍼파라미터 조합을 찾게 됩니다.

 

Next, we need to specify the back-end for job executions. Here we just consider the distribution on a local machine where parallel jobs are executed as sub-processes. However, for large scale HPO, we could run this also on a cluster or cloud environment, where each trial consumes a full instance.

 

다음으로 작업 실행을 위한 백엔드를 지정해야 합니다. 여기서는 병렬 작업이 하위 프로세스로 실행되는 로컬 시스템에서의 배포를 고려합니다. 그러나 대규모 HPO의 경우 각 평가판이 전체 인스턴스를 사용하는 클러스터 또는 클라우드 환경에서도 이를 실행할 수 있습니다.

 

trial_backend = PythonBackend(
    tune_function=hpo_objective_lenet_synetune,
    config_space=config_space,
)

위의 코드는 실험을 실행하기 위해 SyneTune 라이브러리의 Python 백엔드를 설정하는 부분입니다.

  1. trial_backend = PythonBackend(...): PythonBackend는 SyneTune 라이브러리에서 실험을 수행하기 위한 백엔드(실행 환경)를 설정하는데 사용됩니다. 이 백엔드는 Python 코드를 실행하는 데 사용됩니다.
  2. tune_function=hpo_objective_lenet_synetune: tune_function 매개변수에는 하이퍼파라미터 최적화 실험을 실행할 함수를 지정합니다. 여기서는 hpo_objective_lenet_synetune 함수를 지정하여 이 함수가 하이퍼파라미터 튜닝을 수행하도록 합니다.
  3. config_space=config_space: config_space 매개변수에는 하이퍼파라미터 탐색 공간을 지정합니다. 이전에 정의한 config_space 딕셔너리가 여기에 사용됩니다.

이렇게 설정된 trial_backend는 하이퍼파라미터 최적화 실험을 실행하는 데 필요한 백엔드 설정을 가지고 있습니다. 이제 이 백엔드를 사용하여 하이퍼파라미터 튜닝 실험을 실행할 수 있습니다.

 

We can now create the scheduler for asynchronous random search, which is similar in behaviour to our BasicScheduler from Section 19.2.

 

이제 섹션 19.2의 BasicScheduler와 동작이 유사한 비동기 무작위 검색을 위한 스케줄러를 생성할 수 있습니다.

 

scheduler = RandomSearch(
    config_space,
    metric=metric,
    mode=mode,
    points_to_evaluate=[initial_config],
)

위의 코드는 랜덤 서치(Random Search)를 사용하여 하이퍼파라미터 튜닝 실험을 설정하는 부분입니다.

  1. scheduler = RandomSearch(...): RandomSearch는 랜덤 서치 최적화 전략을 사용하는 스케줄러를 설정하는데 사용됩니다.
  2. config_space: config_space 매개변수에는 하이퍼파라미터 탐색 공간을 지정합니다. 이전에 정의한 config_space 딕셔너리가 여기에 사용됩니다.
  3. metric=metric: metric 매개변수에는 평가 지표(metric)를 지정합니다. 이전에 설정한 metric 변수가 사용됩니다. 이 경우 "validation_error"가 평가 지표로 사용됩니다.
  4. mode=mode: mode 매개변수에는 최적화 모드를 지정합니다. 이전에 설정한 mode 변수가 사용됩니다. 이 경우 "min" 모드로 설정되어 있으므로 평가 지표를 최소화하려고 시도할 것입니다.
  5. points_to_evaluate=[initial_config]: points_to_evaluate 매개변수에는 초기 하이퍼파라미터 설정을 포함하는 리스트를 지정합니다. 이전에 정의한 initial_config 변수가 사용됩니다. 이는 랜덤 서치의 시작점으로 사용됩니다.

이렇게 설정된 scheduler는 랜덤 서치 최적화 전략을 사용하여 하이퍼파라미터 탐색을 수행합니다. 랜덤 서치는 주어진 하이퍼파라미터 탐색 공간에서 무작위로 하이퍼파라미터 조합을 샘플링하고, 해당 조합을 평가하여 최적의 조합을 찾는 방법 중 하나입니다.

INFO:syne_tune.optimizer.schedulers.fifo:max_resource_level = 10, as inferred from config_space
INFO:syne_tune.optimizer.schedulers.fifo:Master random_seed = 2737092907

Syne Tune also features a Tuner, where the main experiment loop and bookkeeping is centralized, and interactions between scheduler and back-end are mediated.

 

Syne Tune에는 주요 실험 루프와 장부를 중앙 집중화하고 스케줄러와 백엔드 간의 상호 작용을 중재하는 튜너 기능도 있습니다.

 

stop_criterion = StoppingCriterion(max_wallclock_time=max_wallclock_time)

tuner = Tuner(
    trial_backend=trial_backend,
    scheduler=scheduler,
    stop_criterion=stop_criterion,
    n_workers=n_workers,
    print_update_interval=int(max_wallclock_time * 0.6),
)

위의 코드는 하이퍼파라미터 튜닝 실험을 위한 Tuner 객체를 설정하는 부분입니다.

  1. stop_criterion = StoppingCriterion(max_wallclock_time=max_wallclock_time): StoppingCriterion은 실험이 종료될 조건을 설정하는데 사용됩니다. 이전에 정의한 max_wallclock_time 변수를 사용하여 실험이 최대 실행 시간을 초과하면 종료되도록 설정합니다.
  2. tuner = Tuner(...): Tuner 객체를 설정합니다. 이 객체는 하이퍼파라미터 튜닝 실험을 제어하고 실행하는 역할을 합니다.
    • trial_backend: trial_backend 매개변수에는 실험을 실행할 백엔드(실행 환경)를 지정합니다. 이전에 설정한 trial_backend가 사용됩니다.
    • scheduler: scheduler 매개변수에는 스케줄러를 지정합니다. 이전에 설정한 scheduler가 사용됩니다.
    • stop_criterion: stop_criterion 매개변수에는 실험이 종료될 조건을 지정합니다. 이전에 설정한 stop_criterion이 사용됩니다.
    • n_workers: n_workers 매개변수에는 병렬로 실행될 작업자(worker)의 수를 지정합니다. 이전에 설정한 n_workers 변수가 사용됩니다.
    • print_update_interval: print_update_interval 매개변수에는 실험 진행 상황을 출력할 간격을 설정합니다. 여기서는 최대 실행 시간의 60%에 해당하는 간격으로 설정되어 있습니다.

Tuner 객체는 설정된 백엔드와 스케줄러를 사용하여 하이퍼파라미터 튜닝 실험을 실행하며, 종료 조건이 충족되거나 최대 실행 시간이 초과되면 실험을 종료합니다.

 

Let us run our distributed HPO experiment. According to our stopping criterion, it will run for about 12 minutes.

 

분산된 HPO 실험을 실행해 보겠습니다. 우리의 중지 기준에 따르면 약 12분 동안 실행됩니다.

 

tuner.run()

위의 코드는 설정된 Tuner 객체를 사용하여 하이퍼파라미터 튜닝 실험을 실행하는 부분입니다.

tuner.run() 함수를 호출하면 하이퍼파라미터 튜닝 실험이 시작됩니다. Tuner 객체는 설정된 백엔드와 스케줄러를 사용하여 하이퍼파라미터 공간에서 하이퍼파라미터 조합을 샘플링하고, 각 조합을 평가하여 최적의 하이퍼파라미터 조합을 찾습니다. 설정된 종료 조건이 충족되거나 최대 실행 시간이 초과되면 실험을 종료하고 최적의 하이퍼파라미터 조합 및 결과를 반환합니다.

실험 진행 상황은 이전에 설정한 print_update_interval 간격으로 출력될 것입니다. 이 코드를 실행하면 하이퍼파라미터 튜닝 실험이 실행되고, 최적의 모델을 찾기 위해 하이퍼파라미터 조합을 탐색하게 됩니다.

INFO:syne_tune.tuner:results of trials will be saved on /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958
INFO:root:Detected 4 GPUs
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1 --batch_size 128 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/0/checkpoints
INFO:syne_tune.tuner:(trial 0) - scheduled config {'learning_rate': 0.1, 'batch_size': 128, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1702844732454753 --batch_size 114 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/1/checkpoints
INFO:syne_tune.tuner:(trial 1) - scheduled config {'learning_rate': 0.1702844732454753, 'batch_size': 114, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 0 completed.
INFO:syne_tune.tuner:Trial trial_id 1 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.34019846567238493 --batch_size 221 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/2/checkpoints
INFO:syne_tune.tuner:(trial 2) - scheduled config {'learning_rate': 0.34019846567238493, 'batch_size': 221, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.014628124155727769 --batch_size 88 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/3/checkpoints
INFO:syne_tune.tuner:(trial 3) - scheduled config {'learning_rate': 0.014628124155727769, 'batch_size': 88, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 2 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1114831485450576 --batch_size 142 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/4/checkpoints
INFO:syne_tune.tuner:(trial 4) - scheduled config {'learning_rate': 0.1114831485450576, 'batch_size': 142, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 3 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.014076038679980779 --batch_size 223 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/5/checkpoints
INFO:syne_tune.tuner:(trial 5) - scheduled config {'learning_rate': 0.014076038679980779, 'batch_size': 223, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 4 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.02558173674804846 --batch_size 62 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/6/checkpoints
INFO:syne_tune.tuner:(trial 6) - scheduled config {'learning_rate': 0.02558173674804846, 'batch_size': 62, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 5 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.026035979388614055 --batch_size 139 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/7/checkpoints
INFO:syne_tune.tuner:(trial 7) - scheduled config {'learning_rate': 0.026035979388614055, 'batch_size': 139, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 6 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.24202494130424274 --batch_size 231 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/8/checkpoints
INFO:syne_tune.tuner:(trial 8) - scheduled config {'learning_rate': 0.24202494130424274, 'batch_size': 231, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 7 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.10483132064775551 --batch_size 145 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/9/checkpoints
INFO:syne_tune.tuner:(trial 9) - scheduled config {'learning_rate': 0.10483132064775551, 'batch_size': 145, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 8 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.017898854850751864 --batch_size 51 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/10/checkpoints
INFO:syne_tune.tuner:(trial 10) - scheduled config {'learning_rate': 0.017898854850751864, 'batch_size': 51, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 9 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.9645419978270817 --batch_size 200 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/11/checkpoints
INFO:syne_tune.tuner:(trial 11) - scheduled config {'learning_rate': 0.9645419978270817, 'batch_size': 200, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 11 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.10559888854748693 --batch_size 40 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/12/checkpoints
INFO:syne_tune.tuner:(trial 12) - scheduled config {'learning_rate': 0.10559888854748693, 'batch_size': 40, 'max_epochs': 10}
INFO:syne_tune.tuner:tuning status (last metric is reported)
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0  Completed    10       0.100000         128          10   10.0          0.277195    64.928907
        1  Completed    10       0.170284         114          10   10.0          0.286225    65.434195
        2  Completed    10       0.340198         221          10   10.0          0.218990    59.729758
        3  Completed    10       0.014628          88          10   10.0          0.899920    81.001636
        4  Completed    10       0.111483         142          10   10.0          0.268684    64.427400
        5  Completed    10       0.014076         223          10   10.0          0.899922    61.264475
        6  Completed    10       0.025582          62          10   10.0          0.399520    75.966186
        7  Completed    10       0.026036         139          10   10.0          0.899988    62.261541
        8  Completed    10       0.242025         231          10   10.0          0.257636    58.186485
        9  Completed    10       0.104831         145          10   10.0          0.273898    59.771699
       10 InProgress     8       0.017899          51          10    8.0          0.496118    66.999746
       11  Completed    10       0.964542         200          10   10.0          0.181600    59.159662
       12 InProgress     0       0.105599          40          10      -                 -            -
2 trials running, 11 finished (11 until the end), 436.60s wallclock-time

INFO:syne_tune.tuner:Trial trial_id 10 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.5846051207380589 --batch_size 35 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/13/checkpoints
INFO:syne_tune.tuner:(trial 13) - scheduled config {'learning_rate': 0.5846051207380589, 'batch_size': 35, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 12 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.2468891379769198 --batch_size 146 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/14/checkpoints
INFO:syne_tune.tuner:(trial 14) - scheduled config {'learning_rate': 0.2468891379769198, 'batch_size': 146, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 13 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.12956867470224812 --batch_size 218 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/15/checkpoints
INFO:syne_tune.tuner:(trial 15) - scheduled config {'learning_rate': 0.12956867470224812, 'batch_size': 218, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 14 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.24900745354561854 --batch_size 103 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/16/checkpoints
INFO:syne_tune.tuner:(trial 16) - scheduled config {'learning_rate': 0.24900745354561854, 'batch_size': 103, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 15 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.03903577426988046 --batch_size 80 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/17/checkpoints
INFO:syne_tune.tuner:(trial 17) - scheduled config {'learning_rate': 0.03903577426988046, 'batch_size': 80, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 16 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.01846559300690354 --batch_size 183 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/18/checkpoints
INFO:syne_tune.tuner:(trial 18) - scheduled config {'learning_rate': 0.01846559300690354, 'batch_size': 183, 'max_epochs': 10}
INFO:syne_tune.stopping_criterion:reaching max wallclock time (720), stopping there.
INFO:syne_tune.tuner:Stopping trials that may still be running.
INFO:syne_tune.tuner:Tuning finished, results of trials can be found on /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958
--------------------
Resource summary (last result is reported):
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0  Completed    10       0.100000         128          10     10          0.277195    64.928907
        1  Completed    10       0.170284         114          10     10          0.286225    65.434195
        2  Completed    10       0.340198         221          10     10          0.218990    59.729758
        3  Completed    10       0.014628          88          10     10          0.899920    81.001636
        4  Completed    10       0.111483         142          10     10          0.268684    64.427400
        5  Completed    10       0.014076         223          10     10          0.899922    61.264475
        6  Completed    10       0.025582          62          10     10          0.399520    75.966186
        7  Completed    10       0.026036         139          10     10          0.899988    62.261541
        8  Completed    10       0.242025         231          10     10          0.257636    58.186485
        9  Completed    10       0.104831         145          10     10          0.273898    59.771699
       10  Completed    10       0.017899          51          10     10          0.405545    83.778503
       11  Completed    10       0.964542         200          10     10          0.181600    59.159662
       12  Completed    10       0.105599          40          10     10          0.182500    94.734384
       13  Completed    10       0.584605          35          10     10          0.153846   110.965637
       14  Completed    10       0.246889         146          10     10          0.215050    65.142847
       15  Completed    10       0.129569         218          10     10          0.313873    61.310455
       16  Completed    10       0.249007         103          10     10          0.196101    72.519127
       17 InProgress     9       0.039036          80          10      9          0.369000    73.403000
       18 InProgress     5       0.018466         183          10      5          0.900263    34.714568
2 trials running, 17 finished (17 until the end), 722.84s wallclock-time

validation_error: best 0.14451533555984497 for trial-id 13
--------------------

 

The logs of all evaluated hyperparameter configurations are stored for further analysis. At any time during the tuning job, we can easily get the results obtained so far and plot the incumbent trajectory.

 

평가된 모든 하이퍼파라미터 구성의 로그는 추가 분석을 위해 저장됩니다. 튜닝 작업 중 언제든지 지금까지 얻은 결과를 쉽게 얻고 기존 궤적을 그릴 수 있습니다.

 

d2l.set_figsize()
tuning_experiment = load_experiment(tuner.name)
tuning_experiment.plot()

 

19.3.3. Visualize the Asynchronous Optimization Process

Below we visualize how the learning curves of every trial (each color in the plot represents a trial) evolve during the asynchronous optimization process. At any point in time, there are as many trials running concurrently as we have workers. Once a trial finishes, we immediately start the next trial, without waiting for the other trials to finish. Idle time of workers is reduced to a minimum with asynchronous scheduling.

 

아래에서는 비동기 최적화 프로세스 동안 모든 시행(플롯의 각 색상은 시행을 나타냄)의 학습 곡선이 어떻게 발전하는지 시각화합니다. 어느 시점에서든 작업자 수만큼 동시에 실행되는 시험이 많이 있습니다. 시험이 끝나면 다른 시험이 끝날 때까지 기다리지 않고 즉시 다음 시험을 시작합니다. 비동기 스케줄링으로 작업자의 유휴 시간을 최소화합니다.

 

d2l.set_figsize([6, 2.5])
results = tuning_experiment.results

for trial_id in results.trial_id.unique():
    df = results[results["trial_id"] == trial_id]
    d2l.plt.plot(
        df["st_tuner_time"],
        df["validation_error"],
        marker="o"
    )

d2l.plt.xlabel("wall-clock time")
d2l.plt.ylabel("objective function")

위의 코드는 하이퍼파라미터 튜닝 실험 결과를 시각화하는 부분입니다.

  1. d2l.set_figsize([6, 2.5]): 그림의 크기를 설정하는 부분입니다. 이 경우 그림 크기가 [6, 2.5]로 설정됩니다.
  2. results = tuning_experiment.results: 이전에 실행한 하이퍼파라미터 튜닝 실험의 결과를 가져와 results 변수에 저장합니다.
  3. for trial_id in results.trial_id.unique():: 각 실험 트라이얼(trial)에 대해 반복하는 루프를 시작합니다. results.trial_id.unique()는 실험 트라이얼의 고유한 ID 목록을 가져옵니다.
  4. df = results[results["trial_id"] == trial_id]: 현재 트라이얼에 해당하는 결과만 선택하여 df 변수에 저장합니다.
  5. d2l.plt.plot(...): df에 저장된 결과를 시각화합니다. x축은 st_tuner_time으로, y축은 validation_error로 설정하며, marker="o"를 사용하여 점을 표시합니다.
  6. d2l.plt.xlabel("wall-clock time")와 d2l.plt.ylabel("objective function"): x축과 y축에 라벨을 추가합니다. x축은 "wall-clock time"을 나타내며, y축은 "objective function"을 나타냅니다.

이 코드는 각 실험 트라이얼의 실행 시간에 따른 목표 함수(여기서는 검증 오차)의 변화를 시각화합니다. 실험 결과를 통해 어떤 하이퍼파라미터 조합이 더 나은 성능을 보이는지를 파악할 수 있습니다.

Text(0, 0.5, 'objective function')

 

19.3.4. Summary

We can reduce the waiting time for random search substantially by distribution trials across parallel resources. In general, we distinguish between synchronous scheduling and asynchronous scheduling. Synchronous scheduling means that we sample a new batch of hyperparameter configurations once the previous batch finished. If we have a stragglers - trials that takes more time to finish than other trials - our workers need to wait at synchronization points. Asynchronous scheduling evaluates a new hyperparameter configurations as soon as resources become available, and, hence, ensures that all workers are busy at any point in time. While random search is easy to distribute asynchronously and does not require any change of the actual algorithm, other methods require some additional modifications.

 

병렬 리소스 전반에 걸친 배포 시도를 통해 무작위 검색 대기 시간을 크게 줄일 수 있습니다. 일반적으로 동기 스케줄링과 비동기 스케줄링을 구분합니다. 동기식 스케줄링은 이전 배치가 완료되면 새로운 하이퍼파라미터 구성 배치를 샘플링하는 것을 의미합니다. 다른 시도보다 완료하는 데 더 많은 시간이 걸리는 시도인 낙오자가 있는 경우 작업자는 동기화 지점에서 기다려야 합니다. 비동기식 스케줄링은 리소스를 사용할 수 있게 되는 즉시 새로운 하이퍼파라미터 구성을 평가하므로 모든 작업자가 언제든지 바쁜 상태가 되도록 보장합니다. 무작위 검색은 비동기적으로 배포하기 쉽고 실제 알고리즘을 변경할 필요가 없지만 다른 방법에는 몇 가지 추가 수정이 필요합니다.

 

19.3.5. Exercises

  1. Consider the DropoutMLP model implemented in Section 5.6, and used in Exercise 1 of Section 19.2.
    1. Implement an objective function hpo_objective_dropoutmlp_synetune to be used with Syne Tune. Make sure that your function reports the validation error after every epoch.
    2. Using the setup of Exercise 1 in Section 19.2, compare random search to Bayesian optimization. If you use SageMaker, feel free to use Syne Tune’s benchmarking facilities in order to run experiments in parallel. Hint: Bayesian optimization is provided as syne_tune.optimizer.baselines.BayesianOptimization.
    3. For this exercise, you need to run on an instance with at least 4 CPU cores. For one of the methods used above (random search, Bayesian optimization), run experiments with n_workers=1, n_workers=2, n_workers=4, and compare results (incumbent trajectories). At least for random search, you should observe linear scaling with respect to the number of workers. Hint: For robust results, you may have to average over several repetitions each.
  2. Advanced. The goal of this exercise is to implement a new scheduler in Syne Tune.
    1. Create a virtual environment containing both the d2lbook and syne-tune sources.
    2. Implement the LocalSearcher from Exercise 2 in Section 19.2 as a new searcher in Syne Tune. Hint: Read this tutorial. Alternatively, you may follow this example.
    3. Compare your new LocalSearcher with RandomSearch on the DropoutMLP benchmark.

 

 

 

반응형