답변:
네트워크에서 하나의 출력 만 생성하는 일반적인 경우에 대해 이야기하는 경우 가정이 올바른 것입니다. 알고리즘이 클래스 1 의 모든 인스턴스를 클래스 0 의 50 개 인스턴스로 처리 하도록하려면 다음을 수행해야합니다.
라벨과 관련 가중치로 사전을 정의하십시오.
class_weight = {0: 1.,
1: 50.,
2: 2.}
사전을 매개 변수로 공급하십시오.
model.fit(X_train, Y_train, nb_epoch=5, batch_size=32, class_weight=class_weight)
편집 : " 클래스 1 의 모든 인스턴스를 클래스 0 의 50 인스턴스로 처리 "는 손실 함수에서 이러한 인스턴스에 더 높은 값을 할당한다는 것을 의미합니다. 따라서 손실은 가중 평균이되며, 각 샘플의 가중치는 class_weight 및 해당 클래스로 지정됩니다 .
Keras docs에서 : class_weight : 선택적 딕셔너리 클래스 인덱스 (정수)를 가중치 (float) 값으로 매핑하며, 손실 함수의 가중치를 부여하는 데 사용됩니다 (훈련 중에 만).
class_weight
from을 간단하게 구현할 수 있습니다 sklearn
.
먼저 모듈을 가져 오자
from sklearn.utils import class_weight
클래스 가중치를 계산하려면 다음을 수행하십시오.
class_weights = class_weight.compute_class_weight('balanced',
np.unique(y_train),
y_train)
마지막으로 모델 피팅에 추가하십시오.
model.fit(X_train, y_train, class_weight=class_weights)
주의 :이 게시물을 편집에서 변수 이름을 변경 class_weight 에 class_weight 의 가져온 모듈을 덮어 쓰지 않도록하기 위해. 주석에서 코드를 복사 할 때 적절하게 조정하십시오.
class_weight.compute_class_weight
위해 배열을 생성하려면 Keras와 함께 작동하려면 배열을 dict로 변경해야합니다. 보다 구체적으로, 2 단계 후에class_weight_dict = dict(enumerate(class_weight))
y_train
는 (300096, 3)
numpy 배열입니다. 그래서 class_weight=
선은 나를 형식 오류 제공 : unhashable 유형을 'numpy.ndarray'
y_ints = [y.argmax() for y in y_train]
.
나는 이런 종류의 규칙을 사용합니다 class_weight
:
import numpy as np
import math
# labels_dict : {ind_label: count_label}
# mu : parameter to tune
def create_class_weight(labels_dict,mu=0.15):
total = np.sum(labels_dict.values())
keys = labels_dict.keys()
class_weight = dict()
for key in keys:
score = math.log(mu*total/float(labels_dict[key]))
class_weight[key] = score if score > 1.0 else 1.0
return class_weight
# random labels_dict
labels_dict = {0: 2813, 1: 78, 2: 2814, 3: 78, 4: 7914, 5: 248, 6: 7914, 7: 248}
create_class_weight(labels_dict)
math.log
매우 불균형 한 클래스의 가중치를 매끄럽게합니다! 이것은 다음을 반환합니다.
{0: 1.0,
1: 3.749820767859636,
2: 1.0,
3: 3.749820767859636,
4: 1.0,
5: 2.5931008483842453,
6: 1.0,
7: 2.5931008483842453}
n_total_samples / n_class_samples
각 수업에 사용 했다.
참고 :이 답변은 구식입니다.
모든 클래스에 동일한 가중치를 부여하려면 다음과 같이 class_weight를 "auto"로 설정하면됩니다.
model.fit(X_train, Y_train, nb_epoch=5, batch_size=32, class_weight = 'auto')
class_weight='auto'
Keras 문서 나 소스 코드에서 참조를 찾을 수 없습니다 . 어디서 찾았는지 보여줄 수 있습니까?
class_weight
있으며 영향을주지 않습니다. 따라서이 답변은 정확하지 않습니다.
class_weight는 괜찮지 만 @Aalok이 말했듯이 다중 레이블 클래스가 원 핫 인코딩 인 경우 작동하지 않습니다. 이 경우 sample_weight를 사용 하십시오 .
sample_weight : x와 길이가 같은 선택적 배열로, 각 표본의 모형 손실에 적용 할 가중치를 포함합니다. 시간적 데이터의 경우 모양 (샘플, sequence_length)으로 2D 배열을 전달하여 모든 샘플의 모든 시간 단계에 다른 가중치를 적용 할 수 있습니다. 이 경우 compile ()에 sample_weight_mode = "temporal"을 지정해야합니다.
sample_weights 는 각 학습 샘플에 가중치 를 제공하는 데 사용됩니다 . 즉, 훈련 샘플과 동일한 개수의 요소가있는 1D 배열을 전달해야합니다 (각 샘플의 가중치를 나타냄).
class_weights 는 각 출력 클래스에 가중치 또는 바이어스 를 제공하는 데 사용됩니다 . 즉, 분류하려는 각 클래스에 가중치를 전달해야합니다.
sample_weight는 모양이 평가되므로 numpy 배열을 제공해야합니다.
이 답변을 참조하십시오 : https : //.com/questions/48315094/using-sample-weight-in-keras-for-sequence-labelling
에서 솔루션에 추가 https://github.com/keras-team/keras/issues/2115 . 가양 성 및가 음성에 대해 다른 비용을 원할 경우 클래스 가중치 이상이 필요한 경우. 새로운 keras 버전을 사용하면 아래와 같이 각각의 손실 기능을 무시할 수 있습니다. 그 주 weights
정방 행렬이다.
from tensorflow.python import keras
from itertools import product
import numpy as np
from tensorflow.python.keras.utils import losses_utils
class WeightedCategoricalCrossentropy(keras.losses.CategoricalCrossentropy):
def __init__(
self,
weights,
from_logits=False,
label_smoothing=0,
reduction=losses_utils.ReductionV2.SUM_OVER_BATCH_SIZE,
name='categorical_crossentropy',
):
super().__init__(
from_logits, label_smoothing, reduction, name=f"weighted_{name}"
)
self.weights = weights
def call(self, y_true, y_pred):
weights = self.weights
nb_cl = len(weights)
final_mask = keras.backend.zeros_like(y_pred[:, 0])
y_pred_max = keras.backend.max(y_pred, axis=1)
y_pred_max = keras.backend.reshape(
y_pred_max, (keras.backend.shape(y_pred)[0], 1))
y_pred_max_mat = keras.backend.cast(
keras.backend.equal(y_pred, y_pred_max), keras.backend.floatx())
for c_p, c_t in product(range(nb_cl), range(nb_cl)):
final_mask += (
weights[c_t, c_p] * y_pred_max_mat[:, c_p] * y_true[:, c_t])
return super().call(y_true, y_pred) * final_mask
가장 작은 데이터 세트를 사용하여 손실 함수에서 클래스 가중치를 코딩하는 다음 예제를 발견했습니다. 여기 링크를 참조하십시오 : https://github.com/keras-team/keras/issues/2115
def w_categorical_crossentropy(y_true, y_pred, weights):
nb_cl = len(weights)
final_mask = K.zeros_like(y_pred[:, 0])
y_pred_max = K.max(y_pred, axis=1)
y_pred_max = K.reshape(y_pred_max, (K.shape(y_pred)[0], 1))
y_pred_max_mat = K.equal(y_pred, y_pred_max)
for c_p, c_t in product(range(nb_cl), range(nb_cl)):
final_mask += (weights[c_t, c_p] * y_pred_max_mat[:, c_p] * y_true[:, c_t])
return K.categorical_crossentropy(y_pred, y_true) * final_mask