이 그림을 봐도 뭔소리인지 모르겠다면 아래 링크가 조금은 친절하게 설명해줌


stable diffusion 모델 원리 학술적 대충 설명 - AI그림 채널 (arca.live)


사실 나도 어제까진 막연하게 하이퍼네트워크 그거 그냥 출력이미지를 input, 학습이미지를 output으로 놓은 단순 CNN 모델 아닌가? 라고 생각했는데

찾아봤더니 Textual Inversion이랑 사실 거의 비슷한 원리더라


Textual Inversion (임베딩 훈련) 의 원리 및 탐구내용 - AI그림 학습 채널 (arca.live)


위의 훈련 원리에서 설명 안한 부분이 있는데, 프롬프트의 정보를 지닌 임베딩이 어떤 방식으로 모델에 들어가서 영향을 주는지에 대한 설명을 안했다.


노이즈를 이미지로 역산하여 바꿔주는 마법의 모델으로는 U-NET이 사용되는데, 이 모델 안에는 '어텐션 레이어'가 존재한다. Q, K, V는 각각 Query, Key, Value를 뜻하는데, 사실 논문을 봐도 어텐션 자체가 ㅈ나 복잡한 내용이라 원리를 풀어 쓰기가 어렵다. 대충 임베딩의 정보로부터 그림을 어떻게 그려야 하는지 파악하는 부분이 여기라고 보면 된다. 프롬프트에 red eyes라고 치면 얼굴의 이쪽 부분에 눈이 있으니까 여기에 빨간색을 얹어야겠지? 해주는게 어텐션 레이어라고 보면 되겠다. (옷을 다 입고 있어도 nipples라고 치면 유두가 튀어나오는것도 이런 이유 때문이다)


 Textual Inversion은 역산 과정에서 U-NET과 원하는 임베딩을 제외한 나머지 임베딩 레이어를 잠궈서 오로지 원하는 임베딩 값만 바뀌도록 한다.

그렇다면 하이퍼네트워크는 어떨까?


하이퍼네트워크는 임베딩 값을 input, 어텐션 레이어의 K, V를 output으로 하는 새로운 모델이다.

어텐션 레이어 중간에 들어감으로써 작은 네트워크의 weight로 큰 네트워크의 weight 조절을 이끌어내는 'hyper' network이다.

그래서 역산할때도 하이퍼네트워크를 제외한 나머지 부분들을 다 잠궈서 하이퍼만 학습되도록 하는 것이다.


따라서 이론상으로는 하이퍼가 Textual inversion(임베딩 훈련)보다 더 뛰어나긴 하다.

임베딩 훈련은 어텐션 레이어를 고칠 수가 없어서 아무리 임베딩이 뛰어나도 어텐션 쪽이 병신이면 아무것도 못하지만, 하이퍼는 어텐션 레이어를 고쳐서 주어진 임베딩 값으로부터 더 훌륭한 이미지(훈련 이미지)를 얻어내는 법을 학습할 수 있기 때문이다.


하지만 이것이 시사하는 바 또한 많다.

예를 들면 항상 임베딩의 단점으로 지적되는게 '모델이 배운적이 없는 것은 나타나게 할 수 없다'라는건데, 이건 하이퍼에도 똑같이 해당된다. 못믿겠다면 F222 모델에 하이퍼 돌리고 제대로 나오는지 보면 된다. 당연히 안나오지, 그건 UNET의 어텐션 레이어 이외의 다른 요소들 때문이니까... 그러니까 하이퍼를 통해서 새로운 스타일을 발굴해냈다면 그건 사실 모델이 표현할 수 있었던 범위에 있던 이미지인 것이다. 단지 CLIP 텍스트 모델이 훈련이 덜 되어있어서 찾지를 못했을 뿐.


그리고 하이퍼네트워크는 임베딩 훈련과 반대로 프롬프트 임베딩 정보를 수정할 수 없기 때문에, 태그에 이상한게 들어가거나 태그 자체가 학습이 덜 된 태그라면 그게 하이퍼네트워크의 성능을 떨어트릴 수 있다. 하이퍼는 내가 실험을 잘 안해봐서 태그가 많을수록 좋은지, 적을수록 좋은지는 확실하게 얘기는 못하겠지만 일단 이상한 태그가 들어가면 안된다. DeepDanbooru를 쓰면 가끔 SD가 모르는 캐릭터 태그들이 입력되는데, 캐릭터 태그는 왠만하면 거르고 머리모양, 머리색, 눈색, 옷 정도로만 표현하도록 하자.


마지막으로 하이퍼는 방식 자체가 과적합에 매우 취약하다. 어떠한 임베딩이 들어오든 훈련 이미지에 맞게 조절해야 하니까, 과하게 학습된다면 임베딩보다 그냥 그림 자체를 통째로 외워버리고 만다. 그래서 NovelAI는 페널티를 많이 줬다고 블로그에 썼고, 우리는 Dropout을 쓸 수 있게 되었다. Dropout 꼭 써라. 나중에 Dropout 수치를 바꿀 수 있다면 0.5, 0.7 같은 큰 수치를 넣는것도 나쁘지 않을거라고 봄.


1벡터 임베딩도 성공했으니 하이퍼도 돌려볼까...