2024년 9월 21일 토요일

레이저 데스에더 에센셜(Razer DeathAdder Essential) 유선 마우스

Razer DeathAdder Essential

로지텍 G102 더블클릭현상 나는 거 계속 살려가며 쓰다 이번에 사본 레이저의 염가판 마우스


사이즈: 127mm / 73mm / 43mm, 무게 96g, 케이블 1.8m


측면 버튼

사이즈 비교샷

케이블 묶는 고무줄하고 USB포트 커버가 고급지다.

매뉴얼과 스티커

로지텍하고 MS만 쓰다 레이저는 처음 써 봤는데 묵직하니 좋다.

스위치는 튼튼할 것 같은데 염가판 버전이다보니 휠 고장 이슈가 있는 모양이다. 그래도 보증기간이 2년이니 문제생기면 A/S 받으면 될듯

2024년 8월 19일 월요일

애드거 앨런 포 단편선 후기

이름만 겁나 많이 들어본 애드거 앨런 포

민음사에서 나온 단편집이 도서관에 있길래 빌려봤다. 그냥 시인인줄 알았는데 소설가로 분류됨.

인기도서라 서가에 있는 시간보다 사람들 빌려가는 시간이 많은 것 같음.

연장하려고 다음날 연장신청 하니 바로 누가 예약해놔서 예약불가 뜸.


작가가 미스테리함을 좋아하는 것 같음. 고딕스럽기도 하고 도파민이 계속 터지는 내용들이긴 한데 내 취향과는 거리가 좀 있는듯. 읽어보면 왜 명작이라는지 알 수 있다.

조금 어렵기도 하다. 어디서 소개하기로는 보르헤스의 원조격이라 할 수 있다고도 하는데 보르헤스의 단편을 읽을 때처럼 상상력을 자극하는 부분이 있다.

그중에는 물론 교훈을 주는 단편도 들어있음. 자기반성인지 교훈 전파인지는 모르겠지만 읽는 입장에서는 긍정적으로 보이기도 함.

공통된 소재로는 높은 파도나 소용돌이, 아편 등이 있는데 작가가 약물 경험이 있는지 아니면 그 시대상 마약이 문제가 되어서인지 약에 취한것과 비슷한 상태의 묘사를 하고싶어한다.

이런 부분 나올 때 긍정적으로 읽히지는 않으니 약물에 반대하는 입장에서 그렇게 썼을지도 모르겠다. 내 뇌피셜임.

넷플릭스 드라마 웬즈데이에서도 기숙학교 동문에 까마득한 선배로도 나오는데 드라마의 미스테리한 분위기와 어울리는 것 같다.

조금 어렵지만 재밌는 책이었음

2024년 7월 29일 월요일

PyTorch vs Tensorflow 코드 비교

목표는 파이토치로 모델을 구현하고 안드로이드용 모바일 버전 포팅 시에만 TFLite로 변환
공부하다 보니 근본적인 구조는 비슷한 것 같다.

간단한 모델 비교: PyTorch 버전

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

# 데이터셋 생성
x_data = torch.randn(100, 10)
y_data = torch.randint(0, 2, (100, 1)).float()
dataset = TensorDataset(x_data, y_data)
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)

# 모델 정의
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.layer = nn.Linear(10, 1)
    
    def forward(self, x):
        return torch.sigmoid(self.layer(x))

model = SimpleNN()

# 손실 함수 및 최적화
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 학습 루프
for epoch in range(100):
    for batch_x, batch_y in dataloader:
        # 순전파
        outputs = model(batch_x)
        loss = criterion(outputs, batch_y)
        
        # 역전파 및 최적화
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')

# 추론
with torch.no_grad():
    new_data = torch.randn(5, 10)
    predictions = model(new_data)
    print(predictions)


같은 모델의 Tensorflow 구현버전

import tensorflow as tf

# 데이터셋 생성
x_data = tf.random.normal([100, 10])
y_data = tf.random.uniform([100, 1], minval=0, maxval=2, dtype=tf.int32)

dataset = tf.data.Dataset.from_tensor_slices((x_data, y_data))
dataset = dataset.batch(10).shuffle(100)

# 모델 정의
class SimpleNN(tf.keras.Model):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.layer = tf.keras.layers.Dense(1, activation='sigmoid')
    
    def call(self, x):
        return self.layer(x)

model = SimpleNN()

# 손실 함수 및 최적화
criterion = tf.keras.losses.BinaryCrossentropy()
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

# 학습 루프
for epoch in range(100):
    for batch_x, batch_y in dataset:
        with tf.GradientTape() as tape:
            outputs = model(batch_x)
            loss = criterion(batch_y, outputs)
        
        grads = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))
    
    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch+1}/100], Loss: {loss.numpy():.4f}')

# 추론
new_data = tf.random.normal([5, 10])
predictions = model(new_data)
print(predictions)