(◎◎) {Lass Python die langweiligen Dinge machen) ......... (Hey? Lass uns Python die Hausaufgaben machen} (゜) (゜)

Habt ihr Python die langweiligen Dinge machen lassen?

Ich habe dich nicht tun lassen

Ein Buch auf dem Cover eines Roboters wie diesem C-3PO im Gras

image.png

Es ist berühmt als ein gutes Buch von Python, und viele Leute haben es vielleicht gelesen.

Also, wer hat dieses Buch gelesen und Python die wirklich langweiligen Dinge machen lassen? Ist es nicht ziemlich klein? Ich denke, es gibt viele Menschen, die mit dem Lesen zufrieden sind. Ich war einer von ihnen. Ich habe es vor ungefähr einem Jahr nur einmal gelesen. .. .. war

Das KI-Training hat begonnen

In letzter Zeit ist KI ein Buzz geworden. Es scheint, dass verschiedene Unternehmen damit beginnen, KI einzuführen. Das Unternehmen, für das ich arbeite, ist keine Ausnahme, und ich habe begonnen, KI-Training einzuführen.

Während des Trainings hatte ich die Aufgabe, selbst ein Modell für maschinelles Lernen zu erstellen und handgeschriebene Zeichen vorherzusagen.

Herausforderungsfluss

image.png

1. Modellierung

Definiert ein Modell für tiefes Lernen. Wie viele Ebenen des tiefen Lernens sollten hier verwendet werden, und wie viele Knoten sollten in jeder Ebene verwendet werden? Wir werden die Gesamtkonfiguration und Feinabstimmung des Modells vornehmen.

2. Lernen

Trainieren Sie das Modell, indem Sie Daten (Trainingsdaten) übergeben, in denen das richtige Etikett und das Bild handgeschriebener Zeichen gepaart sind. Hier können Sie das vorläufige Vorhersageergebnis messen, indem Sie einen Teil der Trainingsdaten als Verifizierungsdaten verwenden (siehe 3. Vorhersage). Wir werden das Modell mit dem höchsten vorläufigen Vorhersageergebnis für die nachfolgende Arbeit verwenden.

3. Vorhersage:

Vorhersage handgeschriebener Zeichen durch Übergabe von Daten (Verifizierungsdaten) nur für Bilder handgeschriebener Zeichen. Die Prognose wird als CSV-Datei ausgegeben.

4. Einreichung:

Laden Sie die Vorhersage-CSV-Datei über einen Browser auf den vom Schulungsunternehmen erstellten Webserver hoch.

5. Ergebnisbeleg:

Die Genauigkeit des Vorhersageergebnisses wird auf dem Webserver angezeigt.

Die Herausforderung bestand darin, die Genauigkeit der bestandenen Punktzahl durch Wiederholen der obigen Schritte 1 bis 5 zu ermitteln.

Arbeitsspiel

Nachdem ich es mehrmals wiederholt hatte, kam ich zu dem Schluss, dass dies eine Routinearbeit war. Sobald der Umriss des Modells festgelegt ist, müssen Sie nur noch die Parameter des Modells einstellen und das Lernen wiederholen -> Vorhersage → Übermittlung. Außerdem ist die Wartezeit sehr lang! !! Ich habe mich gefragt, ob dies automatisiert werden kann.

Let's automation with python

Lassen wir Python die langweiligen Dinge tun.

Organisieren Sie den Themenfluss erneut

image.png

Modellierung / Training / Vorhersage

Dies erfolgt in einer interaktiven Python-Ausführungsumgebung namens Jupyter Notebook. Ich dachte, dass Automatisierung realisiert werden könnte, indem der in Jupyter-Notizbuch geschriebene Code in eine Python-Klasse / -Funktion umgewandelt und die für die Optimierung verwendeten Parameter als Argument übergeben werden.

So konvertieren Sie Jupyter-Notebook-Code in eine Python-Datei https://qiita.com/abts/items/25bb611b6d83e646abdd

Übermittlungsergebnis / Ergebnisbeleg

Laden Sie die CSV-Datei, die durch Vorhersage ausgegeben wurde, über Google Chrome auf die Upload-Site hoch. Es scheint, dass der Webbrowser mithilfe einer Python-Bibliothek namens Selenium automatisiert werden kann.

Über Selen https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a

Einschränkung: Pro Tag können nur 5 Dateien hochgeladen werden

Es gab ein Limit, dass Sie nur bis zu 5 vorhergesagte CSV-Dateien pro Tag hochladen können. Ohne dies wäre es einfacher gewesen, den obigen Prozess einfach zu durchlaufen. .. .. Es scheint, dass wir hier etwas entwickeln müssen.

Ablauf der Automatisierung

image.png

Was Menschen tun

Python was du tust

Modellierung / Training / Vorhersage

Dies ist ein Schleifenprozess.

Übermittlung / Erhalt der Ergebnisse

Es wird einmal am Tag wiederholt, nur fünfmal nach Mitternacht. Fünfmal ist die maximale Anzahl von Einreichungen pro Tag.

Implementierung (Codierung)

davor

Wie erwartet kann die Upload-Site des Schulungsunternehmens nicht veröffentlicht werden. Daher verwenden wir dieses Mal stattdessen den Ziffernerkenner von kaggle. Der Grundfluss ändert sich nicht. Außerdem hat kaggle eine API zum Hochladen, aber lassen Sie sich diesmal nicht täuschen (-_-) Ich hoffe, Sie können dies als Reproduktion sehen.

Lassen Sie uns kurz den tatsächlich verwendeten Code erklären.

Code

Klasse für maschinelles Lernen

ai.py


from itertools import product
import os

import pandas as pd
import numpy as np

np.random.seed(2)

from keras.utils.np_utils import to_categorical  # convert to one-hot-encoding
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras.optimizers import RMSprop
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ReduceLROnPlateau
from sklearn.model_selection import train_test_split


class MnistModel(object):
    def __init__(self, train_data_name='train.csv', test_data_csv='test.csv'):
        input_dir = self.get_dir_path('input')
        train_data_path = os.path.join(input_dir, train_data_name)
        test_data_path = os.path.join(input_dir, test_data_csv)
        #Load the data
        self.train = pd.read_csv(train_data_path)
        self.test = pd.read_csv(test_data_path)

    def get_dir_path(self, dir_name):
        """ Function to directory path

        Params:
            dir_name(str): The name of directory
        Return:
            str: The directory path

        """
        base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        data_directory = os.path.join(base_dir, dir_name)
        return data_directory


    def learning_and_predict(self, csv_file_path, config):
        label = self.train["label"]
        train = self.train.drop(labels=["label"], axis=1)


        # Normalize the data
        train = train / 255.0
        test = self.test / 255.0

        # Reshape image in 3 dimensions (height = 28px, width = 28px , canal = 1)
        train = train.values.reshape(-1, 28, 28, 1)
        test = test.values.reshape(-1, 28, 28, 1)

        # Encode labels to one hot vectors (ex : 2 -> [0,0,1,0,0,0,0,0,0,0])
        label = to_categorical(label, num_classes=10)

        # Set the random seed
        random_seed = 2

        # Split the train and the validation set for the fitting
        X_train, X_val, Y_train, Y_val = train_test_split(train, label, test_size=0.1, random_state=random_seed)

        model = Sequential()
        model.add(Conv2D(filters=32, kernel_size=(5, 5), padding='Same',
                              activation='relu', input_shape=(28, 28, 1)))
        model.add(Conv2D(filters=32, kernel_size=(5, 5), padding='Same',
                              activation='relu'))
        model.add(MaxPool2D(pool_size=(2, 2)))
        model.add(Dropout(0.25))
        model.add(Conv2D(filters=64, kernel_size=(3, 3), padding='Same',
                              activation='relu'))
        model.add(Conv2D(filters=64, kernel_size=(3, 3), padding='Same',
                              activation='relu'))
        model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
        model.add(Dropout(0.25))
        model.add(Flatten())
        model.add(Dense(256, activation="relu"))
        model.add(Dropout(0.5))
        model.add(Dense(10, activation="softmax"))

        optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
        model.compile(optimizer=optimizer, loss="categorical_crossentropy", metrics=["accuracy"])

        datagen = ImageDataGenerator(
            featurewise_center=False,  # set input mean to 0 over the dataset
            samplewise_center=False,  # set each sample mean to 0
            featurewise_std_normalization=False,  # divide inputs by std of the dataset
            samplewise_std_normalization=False,  # divide each input by its std
            zca_whitening=False,  # apply ZCA whitening
            rotation_range=config['ROTATION_RANGE'],  # randomly rotate images in the range (degrees, 0 to 180)
            zoom_range=config['ZOOM_RANGE'],  # Randomly zoom image
            width_shift_range=config['WIDTH_SHIFT_RANGE'],  # randomly shift images horizontally (fraction of total width)
            height_shift_range=config['HEIGHT_SHIFT_RANGE'],  # randomly shift images vertically (fraction of total height)
            horizontal_flip=False,  # randomly flip images
            vertical_flip=False)  # randomly flip images
        datagen.fit(X_train)

        learning_rate_reduction = ReduceLROnPlateau(
                                                    monitor='val_acc',
                                                    patience=3,
                                                    verbose=1,
                                                    factor=0.5,
                                                    min_lr=0.00001
        )

        epochs = 1
        batch_size = 86

        history = model.fit_generator(
            datagen.flow(
                X_train,
                Y_train,
                batch_size=batch_size
            ),
            epochs=epochs,
            validation_data=(
                X_val,
                Y_val
            ),
            verbose=2,
            steps_per_epoch=X_train.shape[0] // batch_size,
            callbacks=[learning_rate_reduction])

        results = model.predict(test)
        results = np.argmax(results, axis=1)
        results = pd.Series(results, name="Label")
        submission = pd.concat([pd.Series(range(1, 28001), name="ImageId"), results], axis=1)
        submission.to_csv(csv_file_path, index=False)

        return history.history['val_acc'][0]


Das Modell dieses maschinellen Lernens wurde unter Bezugnahme auf das Folgende (rundes Pakuri) erstellt. https://www.kaggle.com/yassineghouzam/introduction-to-cnn-keras-0-997-top-6

Verwenden Sie die Methode learning_and_predict, um alle Modelle zu erstellen / zu lernen / vorherzusagen. config ist eine Liste von Parametern.

datagen = ImageDataGenerator(
....
    rotation_range=config['ROTATION_RANGE'],  # randomly rotate images in the range (degrees, 0 to 180)
    zoom_range=config['ZOOM_RANGE'],  # Randomly zoom image
    width_shift_range=config['WIDTH_SHIFT_RANGE'],  # randomly shift images horizontally (fraction of total width)
    height_shift_range=config['HEIGHT_SHIFT_RANGE'],  # randomly shift images vertically (fraction of total height)
....
        datagen.fit(X_train)

Dieses Mal werden die Parameter des Bilddatengenerators optimiert.

Parameterdefinition JSON

{
    "CONFIG": [
        {
        "ROTATION_RANGE": 10,
        "ZOOM_RANGE": 0.1,
        "WIDTH_SHIFT_RANGE": 0.1,
        "HEIGHT_SHIFT_RANGE": 0.1
        },
        {
        "ROTATION_RANGE": 10,
        "ZOOM_RANGE": 0.1,
        "WIDTH_SHIFT_RANGE": 0.1,
        "HEIGHT_SHIFT_RANGE": 0.2
        },
        {
        "ROTATION_RANGE": 10,
        "ZOOM_RANGE": 0.1,
        "WIDTH_SHIFT_RANGE": 0.1,
        "HEIGHT_SHIFT_RANGE": 0.3
        },
        {
        "ROTATION_RANGE": 10,
        "ZOOM_RANGE": 0.1,
        "WIDTH_SHIFT_RANGE": 0.1,
        "HEIGHT_SHIFT_RANGE": 0.4
        }
    ]
}

Web-Upload-Klasse

Dies ist eine Klasse zum Hochladen von Predictive CSV auf eine Website. Es wird hauptsächlich in Selen eingesetzt.

import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


DRIVER_FILE_PATH = 'C:\Drivers\chromedriver_win32\chromedriver.exe'
DRIVER_FILE_NAME = 'chromedriver'
TIMEOUT = 30


class BaseBrowserOperator(object):
    """ Base model of browser operator """
    def __init__(self, headless = False):
        driver_path = os.path.join(os.path.dirname(DRIVER_FILE_PATH), DRIVER_FILE_NAME)
        if headless == True:
            options = webdriver.ChromeOptions()
            options.add_argument('--headless')
            self.browser = webdriver.Chrome(driver_path, options=options)
        else:
            self.browser = webdriver.Chrome(driver_path)

    def __del__(self):
        self.browser.close()


class BrowserOperator(BaseBrowserOperator):
    """ The browser operator model """
    def go_to_page(self, url):
        """ Function to go to a page

        Params:
            url(str): The url of page
        """
        self.browser.get(url)

    def click(self, element_xpath, wait=True):
        """ Function to click the page's element

        TODO:
            implement finding element method other than xpath

        Params:
            element_xpath(str): The xpath of element be clicked
            wait(boolean): If disable waiting, please give False.
        """
        if wait:
            self.wait_element(element_xpath)
        self.browser.find_element_by_xpath(element_xpath).click()

    def input_value(self, element_xpath, value, wait=True):
        """ Function to input value to page's element

        TODO:
            implement finding element method other than xpath

        Params:
            element_xpath(str): The xpath of element be clicked
            value(str): The value be inputed
            wait(boolean): If disable waiting, please give False.
        """
        if wait:
            self.wait_element(element_xpath)
        self.browser.find_element_by_xpath(element_xpath).send_keys(value)

    def get_value(self, element_xpath, wait=True):
        """ Function to get value from page's element

        Params:
            element_xpath(str): The xpath of element be clicked
            wait(boolean): If disable waiting, please give False.
        Returns:
            str: Value from page's element
        """
        if wait:
            self.wait_element(element_xpath)
        return self.browser.find_element_by_xpath(element_xpath).text

    def import_cookies(self):
        """ Function to import cookie informations """
        cookies = self.browser.get_cookies()
        for cookie in cookies:
            self.browser.add_cookie({
                'name': cookie['name'],
                'value': cookie['value'],
                'domain': cookie['domain'],
            })

    def wait_element(self, element_xpath):
        """ Function to wait to appear element on page

        TODO:
            implement finding element method other than xpath

        Params:
            element_xpath(str): The xpath of element be used to wait
        """
        WebDriverWait(self.browser, TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, element_xpath)))

    def wait_value(self, element_xpath, value, timeout=300):
        """ Function to wait until element's value equal the specific value

        Params:
            element_xpath(str): The xpath of element be used for wait
            value(str): The used value for wait
            timeout(int): The waiting timeout(sec)
        """
        state = ''
        sec = 0
        while not state == value:
            state = self.browser.find_element_by_xpath(element_xpath).text
            time.sleep(1)
            if sec > timeout:
                raise TimeoutError("Timeout!! The value wasn't available")
            sec += 1


Verwenden Sie jede Methode wie folgt.

Sie können die vorhergesagte CSV-Datei mit kaggle mit dem folgenden Code hochladen.

    def upload_csv_to_kaggle(self, file_path):
        """ Function to upload csv file to kaggle

        Params:
            file_path(str): The path of csv file uploaded
        """
        uploader = BrowserOperator()
        #Übergang zur Kaggle-Seite
        uploader.go_to_page(
            'https://www.kaggle.com/c/digit-recognizer'
        )
        #Klicken Sie auf die Schaltfläche Anmelden
        uploader.click(
            '/html/body/main/div[1]/div/div[1]/div[2]/div[2]/div[1]/a/div/button'
        )
        #Klicken Sie auf Mit Google anmelden
        uploader.click(
            '/html/body/main/div/div[1]/div/form/div[2]/div/div[1]/a/li/span'
        )
        #Geben sie ihre E-Mailadresse ein
        uploader.input_value(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input',
            GOOGLE_MAILADDRESS
        )
        uploader.click(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div'
        )
        #Passwort eingeben
        uploader.input_value(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input',
            GOOGLE_PASSWORD
        )
        uploader.click(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/span/span'
        )
        time.sleep(10) #Ohne Schlaf ging es nicht
     #Cookies importieren
        uploader.import_cookies()
     #Übergang zum CSV-Übermittlungsbildschirm des Ziffernerkenners
        uploader.go_to_page('https://www.kaggle.com/c/digit-recognizer/submit')
        time.sleep(30) #Ohne Schlaf ging es nicht
     #Datei-Upload
        uploader.input_value(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/div/input',
            file_path,
            wait=False
        )
     #Geben Sie einen Kommentar ein
        uploader.input_value(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[2]/div[2]/div/div/div/div[2]/div/div/textarea',
            'test'
        )
        uploader.wait_element(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/ul/li/div/span[1]')
        uploader.click('/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[3]/div[2]/div/a')
        uploader.wait_value(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[2]/div[2]/div/div[3]/div[1]/div[1]/span',
            'Complete'
        )

Task-Ausführungsklasse

homeworker.py


import csv
import datetime
import json
import os
import time


import retrying


from mnist_auto.models.operator import BrowserOperator
from mnist_auto.models.ai import MnistModel


DEFAULT_DAILY_SCORES_DIR = 'daily_scores'
DEFAULT_CSVS_DIR = 'results'
DEFAULT_UPLOADED_SCORE_FILE_NAME = 'uploaded_score.csv'
DEFAULT_KAGGLE_DAILY_LIMIT = 5
COLUMN_DATETIME = 'DATETIME'
COLUMN_SCORE = 'SCORE'
GOOGLE_MAILADDRESS = '[email protected]'
GOOGLE_PASSWORD = 'password'



class BaseHomeworker(object):
    """ Base model of homeworker """

    def __init__(self, daily_score_dir_name, csvs_dir_name):
        self.daily_score_dir_path = self.get_dir_path(daily_score_dir_name)
        self.csvs_dir_path = self.get_dir_path(csvs_dir_name)

    def get_dir_path(self, dir_name):
        """ Function to get directory path
            if direcotry doen't exist, The direcotry will be made

        Params:
            dir_name(str): The directory name
        Returns:
            str: The directory path
        """
        base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        dir_path = os.path.join(base_dir, dir_name)
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)
        return dir_path


class Homeworker(BaseHomeworker):
    """ The homeworker model """

    def __init__(self):
        super().__init__(daily_score_dir_name=DEFAULT_DAILY_SCORES_DIR, csvs_dir_name=DEFAULT_CSVS_DIR)
        self.uploaded_scores = []
        self.config = self.get_confing()
        self.mnist_model = MnistModel()

    def get_confing(self, config_file_name='config.json'):
        """ Function to get configuration with json format

        Params:
            config_file_name(str): The name of config file
        Return:
            dict: The dict including config
        """
        base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        config_file_path = os.path.join(base_dir, config_file_name)
        json_file = open(config_file_path, 'r')
        return json.load(json_file)

    def write_daily_to_file(self, date_ymd, date_ymdhm, score):
        """ Function to write daily data to file

        Params:
            date_ymd(str): The formatted date (YYYYmmdd)
            date_ymdhm(str): The formatted date (YYYYmmddHHMM)
            score(int): The score
        """
        date_ymd = date_ymd + '.csv'
        file_path = os.path.join(self.daily_score_dir_path, date_ymd)
        with open(file_path, 'a', newline='') as csv_file:
            fieldnames = [COLUMN_DATETIME, COLUMN_SCORE]
            writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
            writer.writerow({
                COLUMN_DATETIME: date_ymdhm,
                COLUMN_SCORE: score
            })


    def upload_csv_files(self, date_ymd, num=DEFAULT_KAGGLE_DAILY_LIMIT):
        """ Function to upload designated number csv files

        Params:
            data_ymd(str): The formatted data
            num(int): The number of file that will be uploaded
        """
        targets_uploaded = self.get_tops(date_ymd, num)
        for target in targets_uploaded:
            file_path = os.path.join(self.daily_score_dir_path, target[COLUMN_DATETIME]) + '.csv'
            try:
                self.upload_csv_to_kaggle(file_path)
            except retrying.RetryError:
                continue

    def get_tops(self, date_ymd, num):
        """ Function to get data that have some high score from daily data

        Params:

            num(int): The number of data that will be gotten

        Return:
            list: The list that includes some highest data
        """
        file_name = date_ymd + '.csv'
        file_path = os.path.join(self.daily_score_dir_path, file_name)
        scores = []
        with open(file_path, 'r') as csv_file:
            reader = csv.reader(csv_file)
            for row in reader:
                scores.append({
                    COLUMN_DATETIME: row[0],
                    COLUMN_SCORE: row[1]
                })
        sorted_list = sorted(scores, key=lambda x: x[COLUMN_SCORE], reverse=True)
        if len(sorted_list) < num:
            num = len(sorted_list)
        return sorted_list[:num]

    @retrying.retry(stop_max_attempt_number=3)
    def upload_csv_to_kaggle(self, file_path):
        """ Function to upload csv file to kaggle

        Params:
            file_path(str): The path of csv file uploaded
        """
        uploader = BrowserOperator()
        uploader.go_to_page(
            'https://www.kaggle.com/c/digit-recognizer'
        )
        uploader.click(
            '/html/body/main/div[1]/div/div[1]/div[2]/div[2]/div[1]/a/div/button'
        )
        uploader.click(
            '/html/body/main/div/div[1]/div/form/div[2]/div/div[1]/a/li/span'
        )
        uploader.input_value(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input',
            GOOGLE_MAILADDRESS
        )
        uploader.click(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div'
        )
        uploader.input_value(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input',
            GOOGLE_PASSWORD
        )
        uploader.click(
            '/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/span/span'
        )
        time.sleep(10)
        uploader.import_cookies()
        uploader.go_to_page('https://www.kaggle.com/c/digit-recognizer/submit')
        time.sleep(30)
        uploader.input_value(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/div/input',
            file_path,
            wait=False
        )
        uploader.input_value(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[2]/div[2]/div/div/div/div[2]/div/div/textarea',
            'test'
        )
        uploader.wait_element(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/ul/li/div/span[1]')
        uploader.click('/html/body/main/div[1]/div/div[5]/div[2]/div/div[3]/div[2]/div[2]/div[3]/div[2]/div/a')
        uploader.wait_value(
            '/html/body/main/div[1]/div/div[5]/div[2]/div/div[2]/div[2]/div/div[3]/div[1]/div[1]/span',
            'Complete'
        )
        
    def work(self):
        """ Function to run a series of tasks
                1.  learning and prediction with parameter (It's written on json)
                    one prediction results is outputed as one csv
                2.  Writing learning's score (acc) to another csv.
                3.  Once a day, uploading result csv files to kaggle in high score order
         """
        last_upload_time = datetime.datetime.now()
        for config in self.config['CONFIG']:
            now = datetime.datetime.now()
            now_format_ymdhm = '{0:%Y%m%d%H%M}'.format(now)
            now_format_ymd = '{0:%Y%m%d}'.format(now)
            if (now - last_upload_time).days > 0:
                last_upload_time = now
                self.upload_csv_files()
            csv_file_name = now_format_ymdhm + '.csv'
            csv_file_path = os.path.join(self.csvs_dir_path, csv_file_name)
            score = self.mnist_model.learning_and_predict(csv_file_path=csv_file_path, config=config)
            self.write_daily_to_file(date_ymd=now_format_ymd, date_ymdhm=now_format_ymdhm, score=score)

Die Arbeitsmethode ist der Hauptteil.

Ergebnisansage

Ich konnte die Aufgabe bestehen, indem ich fast schlief! Die Anzahl der Uploads von jedem Auszubildenden wird angezeigt, aber nur ich war eine Größenordnung w

image.png

Lassen Sie Python auch die langweiligen Dinge für Sie erledigen! !! Dann!

Recommended Posts

(◎◎) {Lass Python die langweiligen Dinge machen) ......... (Hey? Lass uns Python die Hausaufgaben machen} (゜) (゜)
"Lassen Sie Python die langweiligen Dinge tun" Übung ~ Befehlszeilen-Mailer ~
MoneyForward Cloud Automatisiert Zeitstempel [Lassen Sie Python die Probleme machen]
Erhalten Sie das Formular in Python und führen Sie verschiedene Aktionen aus
[Version 2020] Lassen Sie Python alle Steuer- und Take-Home-Berechnungen durchführen
Lassen Sie uns mit Python Image Scraping durchführen
[Blender x Python] Lass uns das Material beherrschen !!
Lassen Sie Heroku die Hintergrundverarbeitung mit Python durchführen
Lesen wir die RINEX-Datei mit Python ①
Fassen wir den Python-Codierungsstandard PEP8 (1) zusammen.
[Python] Fassen Sie die rudimentären Dinge über Multithreading zusammen
Fassen wir den Python-Codierungsstandard PEP8 (2) zusammen.
Lassen Sie uns MySQL-Daten mit Python bearbeiten
Einführung in Python Bereiten wir die Entwicklungsumgebung vor
Lassen Sie uns das Git-Commit-Protokoll in Python analysieren!
Wann wirken sich Python-Funktionen auf die Argumente des Aufrufers aus?
[Python] Lassen Sie uns das Modul regelmäßig nach Zeitplan ausführen
Web Scraping mit Python (Wettervorhersage)
Web Scraping mit Python (Aktienkurs)