内なる自分を可視化してみた（画像生成AI）

## 内なる自分
日常の中で、私は時折、自分の内なる心の声と実際の発言で食い違う瞬間がありますよね。まるでアニメのように、内なる自分がリアルな世界に登場するとしたら、それは一体どんな風に表現されるのでしょうか？

今回は、内なる自分がどのような姿なのか、画像生成AIを用いて可視化してみました。


内なる自分は、自分の姿と性格を反映していると仮定し、自身の写真と[性格診断（MBTI）](https://www.16personalities.com/ja/ "MBTI")の結果をもとに画像生成した姿を内なる自分としました。

↓の画像が生成した私の内なる自分です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/b67ba7dc-21b5-0416-19ff-9ed1d4761221.jpeg" width="256" height="381" >


## 開発環境
Google Colab
python 3.10.12

## 画像生成
[日本語版Stable Diffusionの学習済モデル](https://huggingface.co/rinna/japanese-stable-diffusion "日本語版Stable Diffusion")に画像とテキストを入力し、新たな画像を生成するImage to Imageを行いました。また、モデルは[Hugging Face](https://huggingface.co/ "Hugging Face")から利用しています。

[Hugging Face](https://huggingface.co/ "Hugging Face")は、人工知能（AI）の分野で注目をされており、**AIモデルやデータセットを共有・利用することができる**プラットフォームです。様々なデータセットが公開されており、開発者などが簡単にアクセスし、利用できるようになっています。

### Prompt
今回は、[性格診断（MBTI）](https://www.16personalities.com/ja/ "MBTI")の結果をPromptに用いました。
私のMBTIは下図の結果であったため、幹部以外の単語を%が高い順に並べて、
「幹部, 論理的, 計画的, 外交的, 自己主張的, 現実的」をPromptとして、設定しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/1681c610-f4d9-e7e4-ae58-f7ea8f47686e.png" width="192" height="285"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/373f1863-daa8-b4be-f864-2306ab3ecde2.png" width="192" height="285"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/64bfe33e-2172-354e-3477-0e6bd03b3f63.png" width="192" height="285">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/671075a0-0bf8-d7a7-6c79-fac07a511cdc.png" width="192" height="285"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/a7a4634d-d5e3-b8d7-a6fe-b233ee88c374.png" width="192" height="285"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/0b66b573-ab00-7480-b765-be1b8910a4bd.png" width="192" height="285"> 

## 実装 
### パッケージのインストール
```python
pip install diffusers
```
```python
pip install transformers
```
```python
pip install git+https://github.com/rinnakk/japanese-stable-diffusion
```

### ライブラリのインポートとデバイスの設定
* 必要なライブラリやモジュールをインポート
* 利用可能なデバイス（GPUまたはCPU）を確認し、使用するデバイスを設定

```python
import os

from japanese_stable_diffusion import JapaneseStableDiffusionImg2ImgPipeline
from diffusers.pipelines.stable_diffusion.pipeline_onnx_stable_diffusion_img2img import preprocess

import torch
from torch import autocast
device = "cuda" if torch.cuda.is_available() else "cpu"
print("using device is", device)

import matplotlib.pyplot as plt
from PIL import Image
```

### アクセストークンとファイルの準備
* APIへのアクセスに必要なアクセストークンを設定
* 元画像のファイルパスを指定
* 使用するモデルのIDを指定

```python
access_tokens = "Hugging Faceで発行したアクセストークン"

filename = os.path.join("元画像のファイルパス")

model_id = "rinna/japanese-stable-diffusion"

```

### モデルのロードと画像の準備
* 指定したモデルをロードし、画像生成のパイプラインをセットアップ
* 元画像を読み込み、必要に応じてRGB形式に変換
* 元画像をリサイズし、モデルへの入力用に前処理を行う
* リサイズされた元画像を表示

```python
pipe = JapaneseStableDiffusionImg2ImgPipeline.from_pretrained(
    model_id,
    torch_dtype=torch.float16,
    use_auth_token=access_tokens
).to(device)

init_image = Image.open(filename)
if '.png' in filename:
  init_image = init_image.convert('RGB')
resize_image = init_image.resize((512, 762))
input_img = preprocess(resize_image)

plt.imshow(resize_image)
plt.axis('off')
plt.show()
```

### Promptの指定と画像生成
* Promptの指定
* 画像生成の際に使用するランダムシードを設定
* 自動混合精度（autocast）を使用して、画像生成のための入力データを準備し、モデルに渡して画像を生成
* 生成された画像を指定した場所に保存し、表示

```python
prompt = "幹部, 論理的, 計画的, 外交的, 自己主張的, 現実的"

generator = torch.Generator(device).manual_seed(12)

with autocast(device):
  x = torch.from_numpy(input_img).clone()
  output = pipe(prompt=prompt, init_image=x, strength=0.75, guidance_scale=7.5, num_inference_steps=50, generator=generator)
  images = output["images"]

images[0].save("保存する場所")

images[0]
```

### まとめ
* 上記のcodeをまとめたもの
```python
#ライブラリのインポートとデバイスの設定
import os

from japanese_stable_diffusion import JapaneseStableDiffusionImg2ImgPipeline
from diffusers.pipelines.stable_diffusion.pipeline_onnx_stable_diffusion_img2img import preprocess

import torch
from torch import autocast
device = "cuda" if torch.cuda.is_available() else "cpu"
print("using device is", device)

import matplotlib.pyplot as plt
from PIL import Image


#アクセストークンとファイルの準備
access_tokens = "アクセストークン"
filename = os.path.join("元画像のファイルパス")
model_id = "rinna/japanese-stable-diffusion"


#モデルのロードと画像の準備
pipe = JapaneseStableDiffusionImg2ImgPipeline.from_pretrained(
    model_id,
    torch_dtype=torch.float16,
    use_auth_token=access_tokens
).to(device)

init_image = Image.open(filename)
if '.png' in filename:
  init_image = init_image.convert('RGB')
resize_image = init_image.resize((512, 762))
input_img = preprocess(resize_image)

plt.imshow(resize_image)
plt.axis('off')
plt.show()


#Promptの指定と画像生成
prompt = "幹部, 論理的, 計画的, 外交的, 自己主張的, 現実的"

generator = torch.Generator(device).manual_seed(12)

with autocast(device):
  x = torch.from_numpy(input_img).clone()
  output = pipe(prompt=prompt, init_image=x, strength=0.75, guidance_scale=7.5, num_inference_steps=50, generator=generator)
  images = output["images"]

images[0].save("保存する場所")

images[0]
```

## 感想
今回初めて利用した[Hugging Face](https://huggingface.co/ "Hugging Face")には、画像生成だけでなく、動画生成など様々なモデルやデータセットがあるため、他のものも試して見たいと思いました。