카테고리 없음

스파르타 AI-8기 TIL(10/23) -> CNN, 과제 코드 공부

kimjunki-8 2024. 10. 23. 21:01

3. self.conv2 = nn.Conv2d(32, 64, 3, padding=1)

두 번째 합성곱 레이어(conv2)를 정의합니다.
입력 채널 수: 32 (첫 번째 레이어의 출력)
출력 채널 수: 64
커널 크기: 3x3
padding=1으로 인해 출력 크기를 유지합니다.

4. self.fc1 = nn.Linear(64 * 8 * 8, 512)

여기서 왜 8x8인지 설명드리겠습니다.
이것은 대략 Conv2D와 MaxPool2D의 영향이라고 할 수 있습니다. CNN의 합성곱 연산(Convolution)과 풀링 연산(Pooling)을 거치면서 입력 이미지의 크기가 점점 줄어듭니다.

일단, 우리가 처리하는 입력 이미지가 3채널(RGB)의 32x32 픽셀이라고 가정합니다. (입력 이미지 크기는 일반적으로 데이터셋에 따라 다르지만, CIFAR-10 같은 경우 32x32 크기를 사용합니다.)
self.conv1 = nn.Conv2d(3, 32, 3, padding=1)
conv1을 통과하면 출력 크기는 여전히 32x32이지만, 출력 채널이 32개로 증가합니다.

Max Pooling 적용
self.pool = nn.MaxPool2d(2, 2)
Max Pooling은 2x2 크기의 필터를 사용하여 이미지 크기를 절반으로 줄입니다.
Max Pooling을 통과한 후, 이미지의 크기는 32x32 → 16x16으로 줄어듭니다. 채널 수는 여전히 32개입니다.


conv2의 출력
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
conv2를 통과한 후, 출력 크기는 여전히 16x16이지만, 출력 채널은 64개로 증가합니다.
두 번째 Max Pooling 적용

두 번째 Max Pooling을 통과하면 이미지의 크기는 다시 절반으로 줄어듭니다. 16x16 → 8x8로 축소됩니다.채널 수는 64개로 유지됩니다.

64 * 8 * 8의 의미 64: 두 번째 Convolutional Layer에서 출력된 채널 수 (64개의 특징 맵). 8x8: 두 번째 Max Pooling을 거친 후 이미지의 공간적 크기(가로 8, 세로 8).

이 데이터를 Flatten(평탄화)하여 Fully Connected Layer에 입력으로 주기 위해 fc1에서 사용합니다.
3. fc1에서의 Flatten 과정
x = x.view(-1, 64 * 8 * 8)
위 코드에서 view 함수를 사용해 데이터를 1차원 벡터로 펼쳐서, fc1에 입력할 수 있도록 합니다. 이 경우, 64 * 8 * 8은 펼친 후의 입력 크기를 나타냅니다.
그래서 self.fc1 = nn.Linear(64 * 8 * 8, 512)는 64개의 채널에 8x8 크기의 특징 맵을 512개의 뉴런으로 연결하는 Fully Connected Layer를 의미합니다.
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
transforms.Normalize(mean, std)에서 평균과, 표준편차인데 왜 값이 3개씩 들어가있는지는, 바로 RGB 3채널 이미지이기 때문입니다. RGB 이미지는 빨간색(R), 초록색(G), 파란색(B) 세 가지 색상 채널로 이루어져 있습니다. 따라서 각 채널에 대해 정규화할 평균과 표준편차를 따로 줄 수 있어요. 그래서 (0.5, 0.5, 0.5)라는 값은 각 채널(R, G, B)에 대해 평균이 0.5인 값을 빼고, (0.5, 0.5, 0.5)라는 표준편차로 나눈다는 의미입니다.

도전 과제 코드 공부
# 전처리 함수
def preprocess_text(text):
    if isinstance(text, float):
        return ""
    text = text.lower()  # 대문자를 소문자로
    text = re.sub(r'[^\w\s]', '', text)  # 구두점 제거
    text = re.sub(r'\d+', '', text)  # 숫자 제거
    text = text.strip()  # 띄어쓰기 제외하고 빈 칸 제거
    return text

1. if isinstance(text, float):

           return ""

isinstance(text, float) ->
isintance ->
isinstance()는 파이썬에서 사용되는 내장 함수로, 특정 객체가 지정된 클래스나 데이터 타입에 속하는지를 확인하는 데 사용됩니다. 즉, 주어진 객체가 특정 타입인지를 체크하는 함수입니다.
구조 -> isinstance(객체, 클래스 또는 타입)

isinstance()의 결과
주어진 객체가 해당 클래스나 타입에 속하면 True를 반환합니다.
그렇지 않으면 False를 반환합니다

그런데 text가 어떻게 float에 있을 수 있냐고 하실 수 있습니다. 사실 텍스트 데이터에서 float 타입이 발생할 수 있는 이유는 데이터셋에 결측치(NaN) 가 포함될 때입니다. 결측치는 텍스트 데이터프레임에서 보통 NaN 값으로 나타나며, 이 NaN 값은 부동소수점으로 취급되기 때문에 float 타입으로 간주됩니다.

쉽게 말해, 일반적으로 데이터프레임에서 값이 없는 결측치(Null 또는 NaN)로 표현된 값들은 float로 인식됩니다.

그렇게 NaN부분은 return ""을 통해 빈 문자열 ""을 반환합니다.

2. text = text.lower()

매우 간단히 말해, 들어온 text들을 전부 소문자로 바꿔줍니다. 이는 대소문자 구분을 없애기 위한 것입니다. 예를 들어, "Hello"와 "hello"를 동일하게 취급합니다.

3. text = re.sub(r'[^\w\s]', '', text)

여기서 re.sub는 ->
구조 -> re.sub(pattern, replacement, string)로 사용되며,
pattern: 찾고자 하는 정규 표현식 패턴.
replacement: 찾은 패턴을 어떻게 대체할지 지정하는 값. 여기서는 빈 문자열 ' '로 대체하므로, 해당 패턴은 제거됩니다.
string: 패턴을 찾을 대상이 되는 문자열.

r'': 원시 문자열 문자열 앞의 r은 원시 문자열 (raw string)을 의미합니다. 정규 표현식에서 백슬래시(\)를 특수 문자로 해석하지 않고 그대로 사용할 수 있도록 해줍니다.

[]: 대괄호 안의 문자 클래스 대괄호 []는 문자 클래스를 정의하는 부분으로, 해당 클래스 안의 문자 중 하나라도 있으면 매칭됩니다.

^: 부정 연산자 대괄호 안에서 ^는 부정 (not)을 의미합니다. 즉, [^\w\s]는 \w나 \s가 아닌 문자들을 의미합니다.

\w: 단어 문자 (word character) \w는 영문자, 숫자, 그리고 밑줄(_)을 포함한 "단어 문자"를 의미합니다. 정규 표현식에서 \w는 아래와 같은 문자들을 매칭합니다:
1. 영문 알파벳 대소문자 (A-Z, a-z)
2. 숫자 (0-9)
3. 밑줄 (_)

\s: 공백 문자 (whitespace) \s는 공백 문자 (스페이스, 탭, 줄바꿈 등)를 의미합니다. 즉, 공백 문자를 매칭하는 정규 표현식입니다.

즉, r'[^\w\s]' [^\w\s]는 단어 문자도 아니고 공백 문자도 아닌 문자들을 찾는다는 뜻입니다. 즉, 알파벳, 숫자, 밑줄, 공백을 제외한 모든 문자들을 찾습니다. 이 패턴은 주로 구두점, 특수 문자 등을 찾을 때 사용됩니다.

'': 빈 문자열 찾은 패턴을 빈 문자열로 대체하라는 의미입니다. 즉, 구두점이나 특수 문자를 없애는 것과 같습니다.

정규 표현식 r'[^\w\s]'**는 주어진 문자열에서 알파벳, 숫자, 밑줄, 공백을 제외한 문자들을 찾습니다. 이 패턴에 맞는 문자는 빈 문자열로 대체되어 제거됩니다. 결과적으로 구두점이나 특수 문자가 모두 제거된 문자열이 반환됩니다. 예를 들어 문장안에 ',', '!', "'s", '#', '?' 같은 구두점과 특수 문자가 모두 제거되는겁니다.

그리고 이 모든 데이터는 text에서 가져오기에, 마지막에 어디서 가져올지 정하는 부분입니다.

4. text = re.sub(r'\d+', '', text)

아까 배운 글을 토대로하면, re.sub(r'\d+', '', text)는 숫자 자체를 없애는 기능을 수행합니다. 여기선 +라는 개념이 있는데,
r'\d'  -> 이 패턴은 한 개의 숫자를 찾습니다.
예를 들어, 문자열 "123"에서 \d는 각각의 숫자(1, 2, 3)를 찾아낼 수 있습니다.

r'\d+' -> 이 패턴은 하나 이상의 연속된 숫자를 찾습니다.
따라서 "123" 같은 경우, \d+는 "123" 전체를 하나의 매칭으로 찾아내게 됩니다.

예를 들어 "The price is 1500 dollars"라는 문장이 있을 때, r'\d+'를 사용하면 "1500"을 한 번에 제거할 수 있습니다. 만약 r'\d'를 사용하면 "1", "5", "0", "0"을 각각 찾아서 처리해야 하므로 더 복잡해집니다.

5. text = text.strip()

strip()는 문자열의 양쪽 끝에 있는 공백(스페이스, 탭 등)을 제거하는(중간에 있는 공백은 제거하지 않습니다.) 기능을 합니다. 이 메서드는 Python의 내장 문자열 메서드인 strip()을 사용하며, 주로 문자열을 다룰 때 불필요한 공백을 제거하여 깔끔한 데이터를 만들기 위해 사용됩니다.

다음 코드
sns.barplot(x=리뷰컬럼, y=리뷰갯수)
plt.xlabel('Score')
plt.ylabel('Count')
plt.title('Distribution of Scores')
plt.show()

1. sns.barplot(x=리뷰컬럼, y=리뷰갯수)

sns.barplot은 Seaborn 라이브러리에서 제공하는 막대 그래프를 그리는 함수입니다. Seaborn은 Matplotlib을 기반으로 한 데이터 시각화 라이브러리로, 통계적 데이터 시각화를 더 쉽게 만들어주는 기능을 제공합니다. barplot은 주로 범주형 데이터의 평균 값을 시각화하는 데 사용됩니다.

나머지는 옛날에 설명했기 때문에, 생략하겠습니다.

오늘은 여기까지.