# pip install datasets evaluate accelerateQuiz-2 (2024.09.24) // 범위: 02wk-1 까지
| 항목 | 허용 여부 | 비고 |
|---|---|---|
| 강의노트 참고 | 허용 | 수업 중 제공된 강의노트나 본인이 정리한 자료를 참고 가능 |
| 구글 검색 | 허용 | 인터넷을 통한 자료 검색 및 정보 확인 가능 |
| 생성 모형 사용 | 허용 안함 | 인공지능 기반 도구(GPT 등) 사용 불가 |
1. emotion 자료 탐색 – 10점
(1)-(2) 모두 부분점수 없음.
아래는 Hugging Face의 emotion 데이터셋을 로드하는 코드이다:
from datasets import load_dataset
emotion = load_dataset('emotion')/home/cgb3/anaconda3/envs/hf/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
emotion['train'][-2]는 훈련 데이터의 두 번째 마지막 항목을 출력한다. 출력된 샘플은 다음과 같다.
emotion['train'][-2]{'text': 'i feel like this was such a rude comment and im glad that t',
'label': 3}
출력된 샘플은 딕셔너리 형식으로, text에는 문장 “i feel like this was such a rude comment and im glad that t”이 담겨 있다. 이 문장의 감정은 label 항목에 저장되어 있으며, 값은 3으로 나타난다. label 값은 해당 텍스트가 표현하는 감정을 숫자로 표현한 것이다.
감정 레이블은 총 6가지로 나뉘며, 각각의 감정은 다음과 같이 정의된다:
emotion['train'].features['label'].names['sadness', 'joy', 'love', 'anger', 'fear', 'surprise']
{
0: 'sadness',
1: 'joy',
2: 'love',
3: 'anger',
4: 'fear',
5: 'surprise'
}{0: 'sadness', 1: 'joy', 2: 'love', 3: 'anger', 4: 'fear', 5: 'surprise'}
따라서, 문장 “i feel like this was such a rude comment and im glad that t” 의 감정은 label이 3이므로, “anger”에 해당한다.
(1) emotion 데이터셋의 각 분할(train, validation, test)에서 감정별로 몇 개의 데이터가 있는지를 조사하라. 즉 아래의 표에서 빈칸에 해당하는 숫자를 계산할 수 있는 코드를 제시하라. – 5점
| Dataset | 0:Sadness | 1:Joy | 2:Love | 3:Anger | 4:Fear | 5:Surprise | Total |
|---|---|---|---|---|---|---|---|
| Train | ?? | ?? | ?? | ?? | ?? | ?? | 16000 |
| Validation | ?? | ?? | ?? | ?? | ?? | ?? | 2000 |
| Test | ?? | ?? | ?? | ?? | ?? | ?? | 2000 |
note: 정답예시: 아래와 같은 형식으로 출력하는 코드를 작성하면 정답으로 인정
train
{0: 4666, 1: 5362, 2: 1304, 3: 2159, 4: 1937, 5: 572}
--
validation
{0: 550, 1: 704, 2: 178, 3: 275, 4: 212, 5: 81}
--
test
{0: 581, 1: 695, 2: 159, 3: 275, 4: 224, 5: 66}
--
hint: 아래중 원하는 형태를 이용하여 풀이하면 편리하다.
emotion['train']['label']emotion['train'].to_dict()emotion['train'].to_pandas()
(풀이)
{key: {i:emotion[key]['label'].count(i) for i in set(emotion[key]['label'])} for key in emotion}{'train': {0: 4666, 1: 5362, 2: 1304, 3: 2159, 4: 1937, 5: 572},
'validation': {0: 550, 1: 704, 2: 178, 3: 275, 4: 212, 5: 81},
'test': {0: 581, 1: 695, 2: 159, 3: 275, 4: 224, 5: 66}}
(2) emotion 데이터셋의 test셋에서 각 감정(label)별로 가장 짧은 길이를 가진 텍스트를 출력하는 코드를 작성하라. – 5점
note: 정답예시는 아래와 같다.
['i feels so lame',
'i feel any better',
'i just feel tender',
'i feel so damn agitated',
'i feel alarmed',
'i feel all funny sometimes']
(풀이1)
_라벨0만 = [dct['text'] for dct in emotion['test'] if dct['label']==0]
min(map(len,_라벨0만))
[txt for txt in _라벨0만 if len(txt)==min(map(len,_라벨0만))]['i feels so lame']
def func(_라벨0만):
min(map(len,_라벨0만))
return [txt for txt in _라벨0만 if len(txt)==min(map(len,_라벨0만))]list(map(func,[[dct['text'] for dct in emotion['test'] if dct['label']==lbl] for lbl in range(6)]))[['i feels so lame'],
['i feel any better'],
['i just feel tender'],
['i feel so damn agitated'],
['i feel alarmed'],
['i feel all funny sometimes']]
(풀이2)
df = emotion['test'].to_pandas()
df['length'] = list(map(len,df['text']))
df = df.sort_values('length')
df | text | label | length | |
|---|---|---|---|
| 221 | i feel alarmed | 4 | 14 |
| 1632 | id feel frantic | 4 | 15 |
| 634 | i feels so lame | 0 | 15 |
| 873 | i feel soo lonely | 0 | 17 |
| 1389 | i feel any better | 1 | 17 |
| ... | ... | ... | ... |
| 611 | i couldnt help feeling for him and this awful ... | 0 | 284 |
| 119 | i feel like i know who most of them are by now... | 1 | 287 |
| 966 | i have the joy of allowing kids to feel like t... | 1 | 289 |
| 475 | i feel very honored to have been shortlisted w... | 1 | 294 |
| 618 | i am feeling a little more relaxed i am certai... | 1 | 296 |
2000 rows × 3 columns
for _,subdf in df.groupby('label'):
display(subdf.text.iloc[0])'i feels so lame'
'i feel any better'
'i just feel tender'
'i feel so damn agitated'
'i feel alarmed'
'i feel all funny sometimes'
2. emotion 자료 감성분석 – 80점
(1)은 부분점수 있음, (2)는 부분점수 없음.
(1) 아래의 reference 를 참고하여 emotion에 대한 감성분석모델을 학습하는 코드를 작성하라. – 60점
ref:
- https://guebin.github.io/MP2024/posts/02wk-1.html
- https://huggingface.co/docs/transformers/tasks/sequence_classification
세부지침 – 세부지침을 따르지 않을시 감점이 있음 (지침1은 30점감점 지침2는 5점감점)
지침1. Trainer생성시 eval_dataset에는 emotion['validation']를 전처리한 데이터를 이용하라. (emotion['test'] 가 아니라)
지침2. TrainingArguments에서 num_train_epochs은 1로 설정하라.
hint: imdb 자료의 경우 num_labels = 2 이지만, emotion 자료의 경우 그렇지 않음을 유의하라.
(풀이)
import datasets
import transformers
import evaluate
import numpy as np## Step1
데이터불러오기 = datasets.load_dataset
데이터전처리하기1 = 토크나이저 = transformers.AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
def 데이터전처리하기2(examples):
return 데이터전처리하기1(examples["text"], truncation=True)
## Step2
인공지능생성하기 = transformers.AutoModelForSequenceClassification.from_pretrained
## Step3
데이터콜렉터 = transformers.DataCollatorWithPadding(tokenizer=토크나이저)
def 평가하기(eval_pred):
predictions, labels = eval_pred
predictions = np.argmax(predictions, axis=1)
accuracy = evaluate.load("accuracy")
return accuracy.compute(predictions=predictions, references=labels)
트레이너세부지침생성기 = transformers.TrainingArguments
트레이너생성기 = transformers.Trainer
## Step4
강인공지능생성하기 = transformers.pipeline/home/cgb3/anaconda3/envs/hf/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884
warnings.warn(
## Step1
데이터 = 데이터불러오기('emotion')
전처리된데이터 = 데이터.map(데이터전처리하기2,batched=True)
전처리된훈련자료, 전처리된검증자료 = 전처리된데이터['train'], 전처리된데이터['validation']
## Step2
인공지능 = 인공지능생성하기("distilbert/distilbert-base-uncased", num_labels=6)
## Step3
트레이너세부지침 = 트레이너세부지침생성기(
output_dir="my_awesome_model",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=1, # 전체문제세트를 2번 공부하라..
weight_decay=0.01,
eval_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
push_to_hub=False,
)
트레이너 = 트레이너생성기(
model=인공지능,
args=트레이너세부지침,
train_dataset=전처리된훈련자료,
eval_dataset=전처리된검증자료,
tokenizer=토크나이저,
data_collator=데이터콜렉터,
compute_metrics=평가하기,
)
트레이너.train()Some weights of DistilBertForSequenceClassification were not initialized from the model checkpoint at distilbert/distilbert-base-uncased and are newly initialized: ['classifier.bias', 'classifier.weight', 'pre_classifier.bias', 'pre_classifier.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
| Epoch | Training Loss | Validation Loss | Accuracy |
|---|---|---|---|
| 1 | 0.264700 | 0.203025 | 0.932500 |
TrainOutput(global_step=1000, training_loss=0.5039049835205078, metrics={'train_runtime': 27.0307, 'train_samples_per_second': 591.921, 'train_steps_per_second': 36.995, 'total_flos': 194625049506048.0, 'train_loss': 0.5039049835205078, 'epoch': 1.0})
(2) 1-(2)에서 구해진 text에 대하여 감성분석을 수행하라. – 20점
힌트 1-(2)를 풀지못하였다면 아래의 코드를 이용하여 강제설정할 것
['i feels so lame',
'i feel any better',
'i just feel tender',
'i feel so damn agitated',
'i feel alarmed',
'i feel all funny sometimes']## Step4
강인공지능 = 강인공지능생성하기("sentiment-analysis", model="my_awesome_model/checkpoint-1000")
강인공지능([
'i feels so lame',
'i feel any better',
'i just feel tender',
'i feel so damn agitated',
'i feel alarmed',
'i feel all funny sometimes'
])Hardware accelerator e.g. GPU is available in the environment, but no `device` argument is passed to the `Pipeline` object. Model will be on CPU.
[{'label': 'LABEL_0', 'score': 0.9876920580863953},
{'label': 'LABEL_1', 'score': 0.9838089942932129},
{'label': 'LABEL_2', 'score': 0.9324933886528015},
{'label': 'LABEL_3', 'score': 0.7004759907722473},
{'label': 'LABEL_4', 'score': 0.9285796880722046},
{'label': 'LABEL_5', 'score': 0.8900141716003418}]
3. O/X. – 10점
모두 맞출경우만 정답으로 인정
아래의 제시문을 읽고 올바르게 해석한 사람을 모두 고르라.
나는 50,000개의 “텍스트-라벨” 데이터를 인공지능에게 학습시켰다. 학습이 끝난 후, 50,000개의 데이터 중 20개의 샘플을 무작위로 뽑아 테스트한 결과, 인공지능은 20개의 텍스트에 대한 라벨을 모두 정확히 맞췄다. 이 결과만으로 인공지능이 영화 리뷰에 대한 감성 분석(긍정/부정)을 성공적으로 학습했다고 결론을 내려도 될까?
민지: 제시문에 따르면 50,000개의 훈련 데이터를 사용하여 인공지능을 학습시켰으니, train_data의 크기는 50,000이라고 볼 수 있어.
하니: 50,000개의 데이터 중 일부를 무작위로 샘플링하여 평가하는 것은 올바른 방법이 아니야. 학습에 사용되지 않은 별도의 테스트 데이터를 사용해 성능을 평가해야 인공지능이 제대로 학습했는지 알 수 있어.
다니엘: 하니의 말이 맞아. 50,000개의 데이터 중 20개를 샘플링한 게 아니라, 50,000개의 데이터를 모두 올바르게 맞췄다고 하더라도, 새로운 데이터에 대해 성능이 좋다고 단정할 수는 없어. 중요한 건 새로운 데이터에 대한 예측 성능이지.
해린: 맞아, 훈련 데이터 (=학습 데이터) 를 너무 반복해서 학습하다 보면, 인공지능이 그 데이터에만 지나치게 맞춰져서 새로운 데이터를 잘 처리하지 못할 수 있어. 결국 모델이 학습 데이터에서는 좋은 성능을 내지만, 학습하지 않은 데이터나 실제 환경에서는 성능이 떨어질 위험이 생기는 거야.”
혜인: 그렇구나! 그래서 50,000개의 데이터가 있더라도, 그 중 일부만 학습에 사용하고, 나머지는 평가용으로 따로 남겨두기도 하는 거네. 이렇게 하면 인공지능이 새로운 데이터에서도 잘 작동하는지, 성능을 확인할 수 있는 거잖아?
모두 정답