TensorFlow में नियमितीकरण कैसे जोड़ें?


94

मैंने TensorFlow का उपयोग करके लागू किए गए कई उपलब्ध न्यूरल नेटवर्क कोड में पाया कि नियमितीकरण शर्तों को अक्सर मैन्युअल रूप से नुकसान के मूल्य में एक अतिरिक्त शब्द जोड़कर लागू किया जाता है।

मेरे प्रश्न हैं:

  1. मैन्युअल रूप से करने की तुलना में नियमितीकरण का अधिक सुरुचिपूर्ण या अनुशंसित तरीका है?

  2. मुझे भी लगता है कि get_variableएक तर्क है regularizer। इसका उपयोग कैसे किया जाना चाहिए? मेरे अवलोकन के अनुसार, यदि हम इसे करने के लिए एक रेग्युलर को पास करते हैं (जैसे कि tf.contrib.layers.l2_regularizer, नियमित अवधि का प्रतिनिधित्व करने वाले एक tf.GraphKeys.REGULARIZATOIN_LOSSESटेनर की गणना की जाएगी और नाम के एक ग्राफ संग्रह में जोड़ा जाएगा। क्या यह संग्रह स्वचालित रूप से टेन्सरफ्लो द्वारा उपयोग किया जाएगा (जैसे कि प्रशिक्षण के दौरान ऑप्टिमाइज़र द्वारा उपयोग किया जाता है) या? क्या यह अपेक्षित है कि मैं उस संग्रह का उपयोग स्वयं करूं?


1
बस सुपर स्पष्ट होने के लिए, यह करने का तरीका है S = tf.get_variable(name='S', regularizer=tf.contrib.layers.l2_regularizer )?
पिनोचियो

@Pinocchio क्या आपने इसका पता लगाया है?
Euler_Salter 16

2
@Euler_Salter मुझे अब याद नहीं है, क्षमा करें! अब टेंसर प्रवाह का उपयोग नहीं कर रहा है!
पिनोचियो

जवाबों:


70

जैसा कि आप दूसरे बिंदु में कहते हैं, regularizerतर्क का उपयोग करना अनुशंसित तरीका है। आप इसे get_variableअपने में एक बार उपयोग कर सकते हैं या सेट कर सकते हैं variable_scopeऔर आपके सभी चर नियमित हो सकते हैं।

नुकसान ग्राफ में एकत्र किए जाते हैं, और आपको उन्हें इस तरह से अपने लागत फ़ंक्शन में मैन्युअल रूप से जोड़ना होगा।

  reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
  reg_constant = 0.01  # Choose an appropriate one.
  loss = my_normal_loss + reg_constant * sum(reg_losses)

उम्मीद है की वो मदद करदे!


2
धन्यवाद दोस्त। मैं सोच रहा था कि TensorFlow में मैन्युअल रूप से उन्हें करने की तुलना में reg शब्दों को संभालने के कुछ और बुद्धिमान तरीके होंगे, ऐसा नहीं लगता: P
Lifu हुआंग

14
BTW, दो सुझाव, मुझे सही अगर मैं गलत हूँ। (1), मुझे लगता है कि reg_constantआवश्यक नहीं हो सकता है, क्योंकि TensorFlow में नियमित रूप से अपने निर्माणकर्ताओं में एक तर्क है scale, ताकि रेग शब्दों के प्रभाव को अधिक सूक्ष्म तरीके से नियंत्रित किया जा सके। और (2) का उपयोग करने की tf.add_nतुलना में थोड़ा बेहतर हो सकता है sum, मुझे लगता है कि योग का उपयोग करके मध्यवर्ती परिणाम को संग्रहीत करने के लिए ग्राफ़ में कई टेंसरों का निर्माण हो सकता है।
लिफू हुआंग

1
तो बस इसे सुपर स्पष्ट करने के लिए, जब मैं नियमित चर को डाल देता हूं S = tf.get_variable(name='S', regularizer=tf.contrib.layers.l2_regularizer ), तो क्या मैं आपके द्वारा सुझाए गए कोड का उपयोग करता हूं? में के रूप में sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))?
पिनोकियो

1
दिखा सकता है कि tf.get_collection (tf.GraphKeys.REGULARIZATION_LOSSES) द्वारा संग्रह का हिस्सा बनने के लिए वज़न चर को कैसे बनाया जा सकता है?
यू शेन

3
ऐसा लगता है कि tf.reduce_sumइसके बजाय इस्तेमाल किया जाना चाहिए sum?
कंप्यूटर

45

मौजूदा उत्तर के कुछ पहलू मेरे लिए तुरंत स्पष्ट नहीं थे, इसलिए यहां एक चरण-दर-चरण मार्गदर्शिका दी गई है:

  1. एक नियमित रूप से परिभाषित करें। यह वह जगह है जहाँ नियमितीकरण स्थिरांक को सेट किया जा सकता है, जैसे:

    regularizer = tf.contrib.layers.l2_regularizer(scale=0.1)
  2. इसके माध्यम से चर बनाएं:

        weights = tf.get_variable(
            name="weights",
            regularizer=regularizer,
            ...
        )

    समान रूप से, नियमित weights = tf.Variable(...)कंस्ट्रक्टर के माध्यम से चर बनाए जा सकते हैं , उसके बाद tf.add_to_collection(tf.GraphKeys.REGULARIZATION_LOSSES, weights)

  3. कुछ lossशब्द परिभाषित करें और नियमितीकरण शब्द जोड़ें:

    reg_variables = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
    reg_term = tf.contrib.layers.apply_regularization(regularizer, reg_variables)
    loss += reg_term

    नोट: ऐसा लगता है कि tf.contrib.layers.apply_regularizationइसे एक के रूप में लागू किया गया है AddN, इसलिए कम या ज्यादा के बराबर है sum(reg_variables)


10
मुझे लगता है कि आप नियमित रूप से दो बार आवेदन कर रहे हैं - दोनों चरण और चरण 3 में apply_regularizationआवश्यक नहीं हैं। यदि आपको चर बनाते समय नियमित रूप से निर्दिष्ट करना आवश्यक है।
अंतरजाल

2
@interjay कृपया एक उदाहरण दें, ये सभी उत्तर सुपर अस्पष्ट हैं! ऐसा इसलिए है क्योंकि हमेशा कम से कम एक व्यक्ति यह कहते हुए टिप्पणी लिखता है कि उपरोक्त उत्तर में कुछ गलत है।
Euler_Salter

1
@interjay मुझे पूरा यकीन है कि पिछली बार जब मैंने यह परीक्षण किया था, तब दोनों करना आवश्यक था। मुझे यकीन नहीं है कि हालांकि यह बदल गया है।
bluenote10

1
नहीं, इसका कोई मतलब नहीं है क्योंकि तब आपको एक ही नियमित करने वाले को दो कार्यों को पारित करने की आवश्यकता नहीं होगी। प्रलेखन (और नाम) यह स्पष्ट करता REGULARIZATION_LOSSESहै कि नियमित रूप से कुल नुकसान लौटा है, इसलिए आप अनिवार्य रूप से बुला रहे हैं regularizer(regularizer(weight))

1
मुझे लगता है कि यहां भ्रम "समकक्ष" भाग से उपजा है। वह दो अलग-अलग तरीकों का वर्णन करता है और आप एक को चुनते हैं, यह एक तरीका नहीं है जिसमें दो बार नियमितीकरण शामिल है।
gcp ३१'१ at

28

जब से मुझे एक नहीं मिला, मैं एक सरल सही उत्तर दूंगा। आपको दो सरल चरणों की आवश्यकता है, बाकी टेंसरफ़्लो जादू द्वारा किया जाता है:

  1. वैरिएबल या लेयर्स बनाते समय रेग्युलर जोड़ें:

    tf.layers.dense(x, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.001))
    # or
    tf.get_variable('a', regularizer=tf.contrib.layers.l2_regularizer(0.001))
  2. नुकसान को परिभाषित करते समय नियमितीकरण शब्द जोड़ें:

    loss = ordinary_loss + tf.losses.get_regularization_loss()

अगर मैं regularizer = tf.contrib.layers.l2_ अनियमितizer (0.001) द्वारा एक रेग्युलर ऑपशन बना रहा हूँ तो क्या मैं इसे कई लेयर दीक्षाओं में पास कर सकता हूँ? या क्या मुझे प्रत्येक लेयर के लिए एक अलग रेगुलराइज़र बनाने की आवश्यकता है likeregularizer1 = tf.contrib.layers.l2_ अनियमित (0.001), regularizer2 = ................. regularizer3 = ....। .. और इसी तरह?
मिलोमिंदरबिंदर

@ नितिन आप उसी रेगुलराइज़र का इस्तेमाल कर सकते हैं। यह सिर्फ एक पायथन फ़ंक्शन है जो अपने तर्क के रूप में वज़न को नुकसान पर लागू होता है।
एलैक्सी

1
यह सबसे सुरुचिपूर्ण समाधान जैसा दिखता है लेकिन क्या यह वास्तव में काम करता है? कैसे कहते हैं reg_variables से अलग है = tf.get_collection (tf.GraphKeys.REGULARIZATION_LOSSES) reg_term = tf.contrib.layers.apply_regularization (regularizer, reg_variables) नुकसान + = reg_term
GeorgeOfTheRF

1
मैं केवल यह उल्लेख करना चाहता हूं कि tf.contrib.layers.fully_connected tf.layers.dense को प्रतिस्थापित कर सकता है और, इसके अलावा, अधिक कार्यक्षमताओं को जोड़ सकता है। इन को देखें: इस , यह है, और यह
ओसामा सलाह

16

contrib.learnलाइब्रेरी के साथ ऐसा करने का एक अन्य विकल्प टेंसरफ्लो वेबसाइट पर डीप एमएनआईएसटी ट्यूटोरियल के आधार पर निम्नानुसार है । पहले, यह मानते हुए कि आपने संबंधित पुस्तकालयों (जैसे import tensorflow.contrib.layers as layers) को आयात किया है , आप एक अलग विधि में एक नेटवर्क को परिभाषित कर सकते हैं:

def easier_network(x, reg):
    """ A network based on tf.contrib.learn, with input `x`. """
    with tf.variable_scope('EasyNet'):
        out = layers.flatten(x)
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)
        out = layers.fully_connected(out, 
                num_outputs=10, # Because there are ten digits!
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = None)
        return out 

फिर, एक मुख्य विधि में, आप निम्न कोड स्निपेट का उपयोग कर सकते हैं:

def main(_):
    mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
    x = tf.placeholder(tf.float32, [None, 784])
    y_ = tf.placeholder(tf.float32, [None, 10])

    # Make a network with regularization
    y_conv = easier_network(x, FLAGS.regu)
    weights = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'EasyNet') 
    print("")
    for w in weights:
        shp = w.get_shape().as_list()
        print("- {} shape:{} size:{}".format(w.name, shp, np.prod(shp)))
    print("")
    reg_ws = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES, 'EasyNet')
    for w in reg_ws:
        shp = w.get_shape().as_list()
        print("- {} shape:{} size:{}".format(w.name, shp, np.prod(shp)))
    print("")

    # Make the loss function `loss_fn` with regularization.
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
    loss_fn = cross_entropy + tf.reduce_sum(reg_ws)
    train_step = tf.train.AdamOptimizer(1e-4).minimize(loss_fn)

यह काम करने के लिए आपको पहले से जुड़े MNIST ट्यूटोरियल का पालन करने और संबंधित पुस्तकालयों को आयात करने की आवश्यकता है, लेकिन TensorFlow को सीखने के लिए यह एक अच्छा व्यायाम है और यह देखना आसान है कि नियमितीकरण आउटपुट को कैसे प्रभावित करता है। यदि आप एक तर्क के रूप में एक नियमितीकरण लागू करते हैं, तो आप निम्नलिखित देख सकते हैं:

- EasyNet/fully_connected/weights:0 shape:[784, 200] size:156800
- EasyNet/fully_connected/biases:0 shape:[200] size:200
- EasyNet/fully_connected_1/weights:0 shape:[200, 200] size:40000
- EasyNet/fully_connected_1/biases:0 shape:[200] size:200
- EasyNet/fully_connected_2/weights:0 shape:[200, 10] size:2000
- EasyNet/fully_connected_2/biases:0 shape:[10] size:10

- EasyNet/fully_connected/kernel/Regularizer/l2_regularizer:0 shape:[] size:1.0
- EasyNet/fully_connected_1/kernel/Regularizer/l2_regularizer:0 shape:[] size:1.0
- EasyNet/fully_connected_2/kernel/Regularizer/l2_regularizer:0 shape:[] size:1.0

ध्यान दें कि नियमितीकरण भाग आपको उपलब्ध वस्तुओं के आधार पर तीन आइटम देता है।

0, 0.0001, 0.01 और 1.0 के नियमितीकरण के साथ, मुझे उच्च सटीकता की शर्तों के खतरों को दिखाते हुए क्रमशः 0.9468, 0.9476, 0.9183 और 0.1135 के परीक्षण सटीकता मान मिलते हैं।


2
वास्तव में विस्तृत उदाहरण।
stackoverflowuser2010

5

अगर किसी को अभी भी दिख रहा है, तो मैं बस उस पर जोड़ना चाहूँगा tf.keras में आप उन्हें अपनी परतों में तर्क के रूप में पारित करके वजन नियमितीकरण जोड़ सकते हैं। T2orflow Keras ट्यूटोरियल्स साइट से L2 नियमितीकरण को जोड़ने का एक उदाहरण:

model = keras.models.Sequential([
    keras.layers.Dense(16, kernel_regularizer=keras.regularizers.l2(0.001),
                       activation=tf.nn.relu, input_shape=(NUM_WORDS,)),
    keras.layers.Dense(16, kernel_regularizer=keras.regularizers.l2(0.001),
                       activation=tf.nn.relu),
    keras.layers.Dense(1, activation=tf.nn.sigmoid)
])

जहाँ तक मुझे पता है इस विधि के साथ नियमितीकरण के नुकसान को मैन्युअल रूप से जोड़ने की कोई आवश्यकता नहीं है।

संदर्भ: https://www.tensorflow.org/tutorials/keras/overfit_and_underfit#add_weight_ अनियमितकरण


4

मैंने परीक्षण किया tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)और ग्राफ में tf.losses.get_regularization_loss()एक के साथ l2_regularizer, और पाया कि वे उसी मूल्य को वापस करते हैं। मान की मात्रा का निरीक्षण करके, मुझे लगता है कि reg_constant पहले से ही के पैरामीटर को सेट करके मूल्य पर समझ में आता है tf.contrib.layers.l2_regularizer


3

यदि आपके पास सीएनएन है तो आप निम्नलिखित कार्य कर सकते हैं:

आपके मॉडल फ़ंक्शन में:

conv = tf.layers.conv2d(inputs=input_layer,
                        filters=32,
                        kernel_size=[3, 3],
                        kernel_initializer='xavier',
                        kernel_regularizer=tf.contrib.layers.l2_regularizer(1e-5),
                        padding="same",
                        activation=None) 
...

आपके नुकसान फ़ंक्शन में:

onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=num_classes)
loss = tf.losses.softmax_cross_entropy(onehot_labels=onehot_labels, logits=logits)
regularization_losses = tf.losses.get_regularization_losses()
loss = tf.add_n([loss] + regularization_losses)

1

कुछ उत्तर मुझे और भ्रमित करते हैं। मैं इसे स्पष्ट रूप से बनाने के लिए दो तरीके देता हूं।

#1.adding all regs by hand
var1 = tf.get_variable(name='v1',shape=[1],dtype=tf.float32)
var2 = tf.Variable(name='v2',initial_value=1.0,dtype=tf.float32)
regularizer = tf.contrib.layers.l1_regularizer(0.1)
reg_term = tf.contrib.layers.apply_regularization(regularizer,[var1,var2])
#here reg_term is a scalar

#2.auto added and read,but using get_variable
with tf.variable_scope('x',
        regularizer=tf.contrib.layers.l2_regularizer(0.1)):
    var1 = tf.get_variable(name='v1',shape=[1],dtype=tf.float32)
    var2 = tf.get_variable(name='v2',shape=[1],dtype=tf.float32)
reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
#here reg_losses is a list,should be summed 

फिर, इसे कुल नुकसान में जोड़ा जा सकता है


1
cross_entropy = tf.losses.softmax_cross_entropy(
  logits=logits, onehot_labels=labels)

l2_loss = weight_decay * tf.add_n(
     [tf.nn.l2_loss(tf.cast(v, tf.float32)) for v in tf.trainable_variables()])

loss = cross_entropy + l2_loss

1
इस कोड स्निपेट के लिए धन्यवाद, जो कुछ सीमित, तत्काल सहायता प्रदान कर सकता है। एक उचित व्याख्या यह दर्शाती है कि यह समस्या का एक अच्छा समाधान क्यों है, यह दिखाते हुए इसके दीर्घकालिक मूल्य में बहुत सुधार करेगा और यह भविष्य के पाठकों को अन्य, समान प्रश्नों के साथ और अधिक उपयोगी बना देगा। कृपया कुछ स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें, जिसमें आपके द्वारा की गई धारणाएँ शामिल हैं।
मैक्सिमिलियन पीटर्स

1

tf.GraphKeys.REGULARIZATION_LOSSES स्वचालित रूप से नहीं जोड़ा जाएगा, लेकिन उन्हें जोड़ने का एक सरल तरीका है:

reg_loss = tf.losses.get_regularization_loss()
total_loss = loss + reg_loss

tf.losses.get_regularization_loss()तत्व-वार tf.add_nकी प्रविष्टियों का योग करने के लिए उपयोग करता है tf.GraphKeys.REGULARIZATION_LOSSEStf.GraphKeys.REGULARIZATION_LOSSESआमतौर पर स्केलर की एक सूची होगी, जो नियमित कार्यों का उपयोग करके गणना की जाएगी। इसमें कॉल से प्रविष्टियां मिलती tf.get_variableहैं जो regularizerनिर्दिष्ट पैरामीटर हैं। आप उस संग्रह को मैन्युअल रूप से भी जोड़ सकते हैं। यह तब उपयोगी होगा जब उपयोग करना होगा tf.Variableऔर गतिविधि नियमित या अन्य नियमित नियमितीकरण निर्दिष्ट करते समय भी। उदाहरण के लिए:

#This will add an activity regularizer on y to the regloss collection
regularizer = tf.contrib.layers.l2_regularizer(0.1)
y = tf.nn.sigmoid(x)
act_reg = regularizer(y)
tf.add_to_collection(tf.GraphKeys.REGULARIZATION_LOSSES, act_reg)

(इस उदाहरण में यह निश्चित रूप से x को नियमित करने के लिए अधिक प्रभावी होगा, क्योंकि y वास्तव में बड़े x के लिए समतल होता है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.