<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>elegant-universe.log</title>
        <link>https://velog.io/</link>
        <description>AI Engineer 도전</description>
        <lastBuildDate>Tue, 25 Jul 2023 14:11:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. elegant-universe.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/elegant-universe" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[url to numpy, tensor]]></title>
            <link>https://velog.io/@elegant-universe/url-to-numpy-tensor</link>
            <guid>https://velog.io/@elegant-universe/url-to-numpy-tensor</guid>
            <pubDate>Tue, 25 Jul 2023 14:11:34 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-python">import torch
import torchvision.transforms as transforms
from PIL import Image
import requests
from io import BytesIO
import numpy as np
# Replace &#39;your_image_url&#39; with the URL of the image you want to convert

# Step 1: Download the image from the URL
url = &#39;https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Honeycrisp-Apple.jpg/2269px-Honeycrisp-Apple.jpg&#39;
response = requests.get(url)
image = Image.open(BytesIO(response.content))

# Step 2: Convert the image to a PyTorch tensor
# First, convert the image to RGB if it has an alpha channel (RGBA)
if image.mode == &#39;RGBA&#39;:
    image = image.convert(&#39;RGB&#39;)

# Next, convert the PIL image to a PyTorch tensor
transform = transforms.ToTensor()
tensor_image = transform(image)
tensor_image.shape

img = tensor_image.numpy()
image_for_imshow = np.transpose(img ,(1, 2, 0))
print(img.shape)
tensor_image = torch.tensor(img)
print(tensor_image.shape)

import matplotlib.pyplot as plt

plt.imshow(image_for_imshow)</code></pre>
<p><img src="https://velog.velcdn.com/images/elegant-universe/post/a92980b6-45b1-4028-8c3e-5903a7ed8edb/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[torch.no_grad(), to('cpu'), cuda, detach()]]></title>
            <link>https://velog.io/@elegant-universe/pytorch-cpu-cuda</link>
            <guid>https://velog.io/@elegant-universe/pytorch-cpu-cuda</guid>
            <pubDate>Mon, 29 May 2023 14:34:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/elegant-universe/post/0240f9cb-4e40-4577-acbe-026768b4f56f/image.png" alt=""></p>
<pre><code class="language-python">import torch

# Create tensors on CPU and GPU
a = torch.tensor([[1, 2], [3, 4]], device=&#39;cuda&#39;)
b = torch.tensor([[5, 6], [7, 8]], device=&#39;cpu&#39;)
b.to(&#39;cpu&#39;)
c = a + b
c.device</code></pre>
<p>두개의 device가 다른경우 이렇게 연산이 불가능하다.</p>
<p>PyTorch를 사용하다보면, Module을 통해 나온 Tensor을 후처리에 사용하거나, 계산된 loss Tensor을 logging 하는 일이 많다. </p>
<pre><code class="language-python">embeddings = model(x)</code></pre>
<p>이때 embeddings는 GPU에 올라가있는 Tensor 이기 때문에 numpy 혹은 list로의 변환이 필요하다. 오픈소스를 보면 detach(), cpu(), data, numpy(), tolist() 등을 조합해서 변환을 한다. </p>
<hr>
<p><img src="https://velog.velcdn.com/images/elegant-universe/post/637b59c6-80df-4514-8f4d-9c4cdb1606c4/image.png" alt=""></p>
<p><a href="https://pytorch.org/docs/stable/autograd.html#torch.Tensor.detach">https://pytorch.org/docs/stable/autograd.html#torch.Tensor.detach</a></p>
<p>위 파이토치 docs읽어보면 알아야 할것이있는데, PyTorch docs에 따르면 &quot;Returns a new Tensor, detached from the current graph. The result will never require gradient.&quot; 즉 graph에서 분리한 새로운 tensor를 리턴한다. 파이토치는 tensor에서 이루어진 모든 연산을 추적해서 기록해놓는다(graph). 이 연산 기록으로 부터 도함수가 계산되고 역전파가 이루어지게 된다. detach()는 이 연산 기록으로 부터 분리한 tensor을 반환하는 method이다.</p>
<pre><code class="language-python">with torch.no_grad():
  x_t = torch.rand(3,4)
  y_np = np.ones((4, 2), dtype=np.float32)
  x_t @ torch.from_numpy(y_np)  # dot product in torch
  np.dot(x_t.numpy(), y_np)  # the same dot product in numpy</code></pre>
<p>어떤 이유로 역전파 없이 수학적 연산에만 pytorch를 사용하려는 경우 with torch.no_grad()컨텍스트 관리자를 사용할 수 있습니다. 이 경우 계산 그래프가 생성되지 않고 torch.tensors와 np.ndarrays를 서로 바꿔서 사용할 수 있습니다. 그렇지 않다면 detach()를 통해서 바꿔야 한다. </p>
<pre><code class="language-python">import torch

tensor1 = torch.tensor([1.0,2.0],requires_grad=True,device=&#39;cuda&#39;)

print(tensor1) # tensor([1., 2.], device=&#39;cuda:0&#39;, grad_fn=&lt;CopyBackwards&gt;)
print(type(tensor1)) # &lt;class &#39;torch.Tensor&#39;&gt;
print(tensor1.device) # cuda:0

tensor1 = tensor1.detach().to(&#39;cpu&#39;)  
print(tensor1.device) # cpu
print(tensor1) #tensor([1., 2.])
tensor1 = tensor1.numpy() # tensor를 numpy로 바꿔준다.

print(tensor1) # [1. 2.]
print(type(tensor1)) # &lt;class &#39;numpy.ndarray&#39;&gt;</code></pre>
<p>마지막으로 이것을 보면 이해가 빠를것이다. tensor1은 device가 cuda로 설정되어 cuda gpu 메모리에 올라가져있다. 그래서 device를 찍어보면 cuda에 올라가져있고, 그것을 to(&#39;cpu&#39;)를 통해 바꾸었다. 또한, requires_grad 도 true로 되어있어서, 미분 값이 올라가져 있는것을 .detach() 해야한다. 그래야 numpy로 바꿀 수 있다. </p>
<h3 id="summary">summary</h3>
<blockquote>
</blockquote>
<ul>
<li>pytorch tensor는 autograd에 자동으로 미분값이 저장되어있으므로, 쓰지 않을거라면 with torch.no_grad()사용 추천.</li>
<li>cuda와 cpu의 연산이 호환되지 않으므로, 둘의 device를 맞춰줘야한다. </li>
<li>tensor와 numpy 의 연산은 자유롭다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>