python

uv

트러블슈팅

컨벤션


@staticmethod는 클래스와 관련된 기능을 논리적으로 묶어두면서도, 해당 기능이 인스턴스나 클래스의 상태에 의존하지 않는 경우에 사용하는 방식이며, 클래스의 상속과 오버이딩 사용가능

프로세스 관리

subprocess


데코레이터

생성자/반복자

컨텍스트 관리자 및 with

메타클래스

몽키 패칭

from typing import Optional, Union

def divide(dividend: float, divisor: float) -> Optional[float]:
    if divisor == 0.0:
        return None
    return dividend / divisor

def log(level: Union[str, int], message: str) -> None:
    if isinstance(level, int):
        print(f"Level {level}: {message}")
    else:
        print(f"{level.upper()}: {message}")

asyncio : 비동기

메모리관리

descriptors

기본

def outer_func():  
    message = 'Hi'  
    def inner_func():  
        print(message)  
    return inner_func  
my_func = outer_func()  
my_func()  # Hi 가 출력됨
mytuple = (1,2,3)  
myit = iter(mytuple)  
  
print(next(myit))  #1  
print(next(myit))  #2  
print(next(myit))  #3
def yield_test():  
    for i in range(5):  
        yield i  
        print(i,'번째 호출!')  
  
print(type(yield_test())) # <class 'generator'> yield 가 사용되면 generator 가 되나 봄  
  
t = yield_test()  
print(t.__next__()) # 0  
print(t.__next__()) # 0 번째 호출! 1  
print(t.__next__()) # 1 번째 호출! 2  
print(t.__next__()) # 2 번째 호출! 3  
print(t.__next__()) # 3 번째 호출! 4  
#print(t.__next__()) #Error

fastAPI

import asyncio

async def fetch_data():
    print("Fetching data...")
    await asyncio.sleep(2)  # 대기
    print("Data fetched")
    return {"data": "some data"}

async def main():
    print("Main function start")
    data = await fetch_data()
    print(data)
    print("Main function end")
import time

def process_data_in_chunks(file_path, chunk_size):
    start_time = time.time()
    with open(file_path, 'rb') as file:
        while chunk := file.read(chunk_size):
            # 청크 데이터를 처리하는 로직
            process_chunk(chunk)
    end_time = time.time()
    return end_time - start_time

def process_chunk(chunk):
    # 청크 데이터를 처리 코드
    pass

file_path = 'large_data_file.csv'
chunk_sizes = [1024 * 1024, 2 * 1024 * 1024, 5 * 1024 * 1024]  # 1MB, 2MB, 5MB
best_chunk_size = None
best_time = float('inf')

for size in chunk_sizes:
    elapsed_time = process_data_in_chunks(file_path, size)
    print(f'Chunk size: {size} bytes, Time taken: {elapsed_time} seconds')
    if elapsed_time < best_time:
        best_time = elapsed_time
        best_chunk_size = size

print(f'Optimal chunk size: {best_chunk_size} bytes')

pytorch

import torch
import torch.nn as nn

# 완전 연결 계층 정의
fc1 = nn.Linear(9216, 128)

# 가중치와 편향 확인
print(f'가중치 행렬 크기: {fc1.weight.shape}')  # (128, 9216)
print(f'편향 벡터 크기: {fc1.bias.shape}')     # (128)

# 가중치와 편향 초기화 (기본적으로 PyTorch는 Xavier 초기화를 사용함)
nn.init.xavier_uniform_(fc1.weight)
nn.init.zeros_(fc1.bias)

# 가중치와 편향 값 출력
print(f'초기화된 가중치: {fc1.weight}')
print(f'초기화된 편향: {fc1.bias}')

- 가중치 : 입력 뉴런의 값을 특정 비율로 조정하여 출력 뉴런에 영향을 미침. 가중치들을 조정하여 입력 데이터에서 중요한 특징을 추출하고 패턴을 학습
- 가중치 행렬 : (128(출력뉴런 수), 9216(입력 뉴런 수)수
- 편향 : 각 출력 뉴런에 더해지는 추가적인 파라미터, 신경망이 특정 입력 패턴에 대해 더 유연하게 반응 가능, 입력 값이 모두 0일 때도 출력이 특정값을 가질 수 있도록하여 모델이 데이터를 일반화 하는데 도움
- 평향 벡터 : (128(출력 뉴런의 수))

import torch
import torch.nn.functional as F

# 임의의 입력 텐서 생성
x = torch.tensor([-1.0, 0.0, 1.0, 2.0])

# 시그모이드 활성화 함수 적용
sigmoid_y = torch.sigmoid(x)

# tanh 활성화 함수 적용
tanh_y = torch.tanh(x)

print(f'입력 텐서: {x}')
print(f'시그모이드 적용 후 텐서: {sigmoid_y}')
print(f'tanh 적용 후 텐서: {tanh_y}')

- 시그모이드 함수 : 입력 값을 0과 1사이의 값으로 맵핑하는 s자 형태의 비선형 함수(확률 표현할 때 유용)로 미분이 가능하여 기울기 계산에 사용될 수 있음, 극단적인 값에서 매우 평평해지기 때문에 역전파 과정에서 기울기가 매우 작아져서 학습이 거의 이루어지지 않음, 항상 양수라서 학습을 어렵게 만들 수 있음
- 탄젠트(하이퍼볼릭 탄젠트; tanh function) : 1과 1 사이의 값으로 맵핑하는 비선형 함수 :: 시그모이드 함수보다 범위가 크고 0을 중심으로 대칭적이라 학습을 쉽게 만듬

import torch
import torch.nn.functional as F

# 임의의 입력 텐서 생성 (배치 크기: 1, 채널 수: 1, 높이: 4, 너비: 4)
x = torch.tensor([[[[1.0, 2.0, 3.0, 4.0],
                    [5.0, 6.0, 7.0, 8.0],
                    [9.0, 10.0, 11.0, 12.0],
                    [13.0, 14.0, 15.0, 16.0]]]])

print(f'입력 텐서: \n{x}')

# 2x2 최대 풀링 적용
y = F.max_pool2d(x, 2)

print(f'최대 풀링 적용 후 텐서: \n{y}')

- 입력 텐서의 크기는 (1,1,4,4)이며 이는 배치 크기 1, 채널 수 1, 높이 4, 너비 4를 의미
- 2x2 최대 풀링을 적용하면, 각 2x2 영역에서 최대값이 선택(첫 번째 2x2 영역: {1,2,5,6}-> 6, 두번째 2x2 영역 : {3,4,7,8}->8)

dataset과 batch_size

import torch
from torch.utils.data import DataLoader, TensorDataset

# 예제 데이터셋 생성
data = torch.randn(100, 1, 28, 28)  # 100개의 1x28x28 이미지
targets = torch.randint(0, 10, (100,))  # 100개의 레이블 (0에서 9 사이의 정수)

# 텐서 데이터셋 생성
dataset = TensorDataset(data, targets)

# 배치 크기를 32로 설정한 데이터 로더 생성
batch_size = 32
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

# 데이터 로더를 통해 배치 단위로 데이터 순회
for batch_data, batch_targets in dataloader:
    # 여기서 batch_data와 batch_targets는 각각 batch_size만큼의 데이터를 포함
    print(f'Batch data shape: {batch_data.shape}, Batch targets shape: {batch_targets.shape}')

• Preprocessor: 입력 데이터를 모델에 적합한 형태로 변환. (예: 스케일링, 형태 변환, 데이터 증강 등)
• Postprocessor: 모델의 출력을 해석 가능한 형태로 변환. (예: 소프트맥스, 클래스 레이블 변환, 임계값 적용 등)


캐싱


수치 데이터 처리

파이썬 가상환경 라이브러리 삭제