コード例 #1
0
def main():
    args = parser.parse_args()
    enc = get_encoder(args.model_name)
    print('Reading files')
    chunks = load_dataset(enc,
                          args.in_text,
                          args.combine,
                          encoding=args.encoding)
    print('Writing', args.out_npz)
    np.savez_compressed(args.out_npz, *chunks)
コード例 #2
0
def train_single(input_file_path):
    """
    Train model on single device
    Args:
        input_file_path: preprocessed dataset path
    """
    print("Staring training on single device.")
    preprocessed_data = load_dataset(dataset_path=input_file_path,
                                     batch_size=config.batch_size,
                                     epoch_count=config.epoch_count,
                                     bucket=config.buckets)
    _build_training_pipeline(preprocessed_data)
コード例 #3
0
def train_paralle(input_file_path):
    """
    Train model on multi device
    Args:
        input_file_path: preprocessed dataset path
    """
    set_parallel_env()
    print(
        "Starting traning on mutiple devices. |~ _ ~| |~ _ ~| |~ _ ~| |~ _ ~|")
    preprocessed_data = load_dataset(dataset_path=input_file_path,
                                     batch_size=config.batch_size,
                                     epoch_count=config.epoch_count,
                                     rank_size=MultiAscend.get_group_size(),
                                     rank_id=MultiAscend.get_rank(),
                                     bucket=config.buckets,
                                     shuffle=False)
    _build_training_pipeline(preprocessed_data)
コード例 #4
0
def home_app(prev_vars=None):
    dataset = load_dataset()
    st.markdown("""
    # README.md

    Это проект, позволяющий вам быстро оценить данные из датасета.
    Также здесь представлена базовая информация об инструментах 
    визуализации данных, а также построении простейших
    моделей на их основе. 

    Здесь вы можете:
    - Выбрать и посмотреть на конкретные строки датасета;
    - Построить различные графики зависимостей фичей из датасета;
    - Обучить простейшие модели классификации или регрессии на ваших данных.

    В меню слева можно загрузить свой собственный датасет и 
    выбрать страничку дял отображения.
    """)

    st.image('images/main_img.png')
コード例 #5
0
ファイル: graphics.py プロジェクト: LoveSolaristics/Easy-ML
def graphics_app(prev_vars=None):
    dataset = load_dataset()

    PALETTE_LIST_SEABORN = ['Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn',
                            'BuGn_r',
                            'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu',
                            'GnBu_r',
                            'Greens', 'Greens_r',
                            'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn',
                            'PRGn_r',
                            'Paired', 'Paired_r',
                            'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu',
                            'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r',
                            'Purples',
                            'Purples_r',
                            'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu',
                            'RdYlBu_r',
                            'RdYlGn',
                            'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3',
                            'Set3_r',
                            'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu',
                            'YlGnBu_r',
                            'YlGn_r',
                            'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r',
                            'autumn',
                            'autumn_r', 'binary', 'binary_r',
                            'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r',
                            'cool',
                            'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r',
                            'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth',
                            'gist_earth_r',
                            'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar',
                            'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern',
                            'gist_stern_r',
                            'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r',
                            'gnuplot_r',
                            'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'icefire', 'icefire_r',
                            'inferno', 'inferno_r', 'magma', 'magma_r', 'mako', 'mako_r',
                            'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r',
                            'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r',
                            'rocket', 'rocket_r', 'seismic', 'seismic_r', 'spring', 'spring_r',
                            'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b',
                            'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'twilight',
                            'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis',
                            'viridis_r',
                            'vlag', 'vlag_r', 'winter', 'winter_r']
    dataset_columns = list(dataset.columns)
    numeric_columns = dataset.select_dtypes(include=np.number).columns.tolist()

    st.title('Построение графиков')

    st.markdown("""
    Содержание:\n
    1. <a href='#part2.1'>Парные зависимости</a>
    2. <a href='#part2.2'>График распределения</a>
    3. <a href='#part2.3'>Круговая диаграмма</a>
    4. <a href='#part2.4'>Heatmap</a>
    5. <a href='#part2.5'>Pandas Profiling</a>
    6. <a href='#part2.6'>Полезные ссылочки</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Для построения графиков в Python существует целый ряд библиотек.
    Помимо базового `matplotlib.pyplot` и встроенных возможностей `pandas`, рекомендую обратить 
    внимание на [seaborn](seaborn.pydata.org/)  и [plotnine]
    (plotnine.readthedocs.io/en/stable/). 
    Они используются для построения неинтерактивных графиков.

    Также при помощи таких библиотек, 
    как [bokeh](bokeh.org/), 
    [altair](altair-viz.github.io/gallery/index.html#interactive-charts) и 
    [plotly](plotly.com/python/) 
    есть возможность создать не только интерактивные графики, но и анимации!

    [Seaborn](seaborn.pydata.org/) 
    содержит наиболее адекватные дефолтные настройки оформления графиков. 
    Если просто добавить в код `import seaborn`, то картинки станут гораздо симпатичнее. 
    Поэтому используем эту библиотеку для визуализации базовых зависимостей в данных.
    """)

    st.markdown("""
    ## <a id='part2.1'>Парные зависимости</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Даный вид графика показывает отношения между всеми парами переменных, которые
    присутствуют в датасете. Также дополнительные парметры pairplot позволяют
    раскрасить графики в соответствии с какой-либо из переменных.

    Чтобы построить pairplot нужно использовать функцию `seaborn.pairplot`. 
    Документацию для этой функции можно посмотреть 
    [здесь](seaborn.pydata.org/generated/seaborn.pairplot.html).
    """)

    def display_pairplot(df, columns, hue, palette):
        pairplot = sns.pairplot(df[columns], hue=hue, palette=palette)
        st.pyplot(pairplot)

    with st.expander('Основные настройки графика'):
        allowed_columns = st.multiselect('Выберите колонки для построения графика', dataset_columns,
                                         default=dataset_columns)

        pairplot_hue_columns = allowed_columns
        for elem in pairplot_hue_columns:
            if len(dataset[elem].unique()) > 100:
                pairplot_hue_columns.remove(elem)

        pairplot_hue = st.selectbox('Столбец для кодирования цета',
                                    [None] + pairplot_hue_columns)

    with st.expander('Настройки дизайна графика'):
        pairplot_palette = st.selectbox('Выберите палитру для графика',
                                        PALETTE_LIST_SEABORN, key='pairplot_palette')

    st.write("\n\n")
    if st.button('Построить график', key='pairplot_button'):
        try:
            display_pairplot(dataset, allowed_columns, pairplot_hue, pairplot_palette)
        except Exception:
            st.info("""
            При построении графика произошла ошибка.
            Попробуйте ещё раз или измените параметры отображения.
            """)

    st.markdown("""
    ## <a id='part2.2'>График распределения </a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Распределение значений конкретной фичи из датасета можно визуализировать
    при помощи гистограммы и графика плотности распределения. 

    Тот и другой вид диаграмм может быть построен при помощи единой функции
    `seaborn.distplot`. Передевая в неё дополнительный аргумент `kind` можно
    указать, какой конкретно вид диаграммы ввы хотите построить. Прочие параметры
    можно посмотреть 
    [тут](seaborn.pydata.org/generated/seaborn.displot.html#seaborn.displot).
    """)

    def display_distplot(df, column, kind, palette='Blues'):
        sns.set_palette(palette)
        fig = sns.displot(data=df, x=column, kind=kind)
        st.pyplot(fig)

    with st.expander('Основные настройки графика'):
        distplot_kind = st.selectbox('Выберите тип графика', ['hist', 'kde', 'ecdf'])

        distplot_column = st.selectbox('Выберите столбец для построения распределения',
                                       dataset_columns)
    st.write("\n\n")

    with st.expander('Настройки дизайна графика'):
        distplot_palette = st.selectbox('Выберите палитру для графика',
                                        PALETTE_LIST_SEABORN)
    st.write("\n\n")

    if st.button('Построить график', key='distplot_button'):
        try:
            display_distplot(dataset, distplot_column, distplot_kind, distplot_palette)
        except Exception:
            st.info("""
            При построении графика произошла ошибка.
            Попробуйте ещё раз или измените параметры отображения.
            """)

    st.markdown("""
    ## <a id='part2.3'>Круговая диаграмма</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Круговая диаграмма служит ровно для тех же целей, что и гистограмма, но 
    с её помощью можно визуализировать именно процентное распределение данных.

    Ради разнообразия, построим её с помощью библиотеки [plotly](plotly.com/python/).
    Нам понадобится функция `plotly.express.pie`. Графики, построенные с помощью этой библиотеки
    являются интерктивными, так что помимо основной информации можно добавить дополнительную, 
    которая будет отображаться при наведении на части диаграммы. Больше примеров использования
    можно посмотреть по [ссылке](plotly.com/python/pie-charts).
    """)

    def display_pieplot(df, values, names, hover_data=None, template=None):
        if values == names:
            st.info('Выберите различные столбцы. Иначе круговая диаграмма будет неинфромативной')
        else:
            fig = px.pie(df, values=values, names=names, hover_data=hover_data, template=template)
            fig.update_traces(textposition='inside', textinfo='percent+label')
            st.plotly_chart(fig)

    with st.expander('Основные настройки графика'):
        values_column = st.selectbox('Выберите столбец значений',
                                     dataset_columns)

        names_column = st.selectbox('Выберите столбец, по которому будет построено распределение',
                                    dataset_columns)

        pieplot_hover_data = st.multiselect('Выберите столбцы с дополнительной информацией',
                                            dataset_columns)
    st.write('\n\n')

    with st.expander('Настройки дизайна графика'):
        pieplot_template = st.selectbox('Выберите тему для графика',
                                        [None] + list(pio.templates))
    st.write('\n\n')

    if st.button('Построить график', key='pieplot_button'):
        try:
            display_pieplot(dataset, values_column, names_column, pieplot_hover_data,
                            pieplot_template)
        except Exception:
            st.info("""
            При построении графика произошла ошибка.
            Попробуйте ещё раз или измените параметры отображения.
            """)

    st.markdown("""
    ## <a id='part2.4'>Heatmap</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Для того, чтобы понять, насколько в числовом эквиваленте скоррелированы признаки
    можно использовать тепловую карту. Перед этим нужно получить матрицу корреляций
    с помощью метода `DataFrame.corr`, после чего передать получившуюся матрицу в 
    функцию `seaborn.heatmap`. Последняя может не только цвветом показать корреляции,
    но и отобразить числовые значения. Подробности можно почитать в 
    [документации](seaborn.pydata.org/generated/seaborn.heatmap.html).
    """)

    def display_heatmap(df, columns, annot):
        fig, ax = plt.subplots()
        sns.heatmap(df[columns].corr(), ax=ax, annot=annot, linewidths=.5, square=True, fmt='.2f')
        st.write(fig)

    with st.expander('Основные настройки графика'):
        heatmap_annotation = st.selectbox('Нужно ли выводить цифры корреляции', [True, False])

        heatmap_columns = st.multiselect('Выберите числовые столбцы для графика',
                                         numeric_columns, default=numeric_columns)
    st.write('\n\n')

    st.write('\n\n')
    if st.button('Построить график', key='heatmap_button'):
        try:
            display_heatmap(dataset, heatmap_columns, heatmap_annotation)
        except Exception:
            st.info("""
            При построении графика произошла ошибка.
            Попробуйте ещё раз или измените параметры отображения.
            """)

    st.markdown("""
    ## <a id='part2.5'>Pandas Profiling</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Профилирование – процесс, который помогает понять наши данные, а [Pandas Profiling](
    towardsdatascience.com/10-simple-hacks-to-speed-up-your-data-analysis-in-python-ec18c6396e6b) 
    – Python библиотека, которая делает это. Простой и быстрый способ выполнить предварительный 
    анализ данных Python Pandas DataFrame. 

    Функции pandas df.describe() и df.info(), как правило, становятся первым шагом в 
    автоматизации проектирования электронных устройств. Но это даёт лишь базовое представление о 
    данных и мало помогает при больших наборах. Зато функция Pandas Profiling отображает много 
    информации с помощью одной строки кода и в интерактивном HTML-отчёте.

    Для набора данных пакет Pandas Profiling вычисляет следующую статистику:
    """)

    st.image('images/profiling.png',
             caption='Вычисление статистики в пакете Pandas Profiling')

    st.markdown("""Всё, что для этого нужно - это пара строк кода.""")

    st.code("""
    # импорт необходимых пакетов
    import pandas as pd
    import pandas_profiling

    pandas_profiling.ProfileReport(your_dataset)
    """)

    st.markdown("""
    ## <a id='part2.6'>Полезные ссылочки</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    1. [The Python Graph Gallery](www.python-graph-gallery.com/).
        Здесь можно посмотреть на огромное количество видов графиков,
        которые можно построить с использованием Python.
    2. [Сравнение библиотек визуализации](pythonplot.com/).
        Тут есть возможность увидеть, чем отличаются одни и те же
        виды графиков, построенные разными библиотеками. Это не только 
        сраввнение внешнего вида, но и количества кода, необходимого
        для реализации базового функционала.
    3. [Seaborn documentation](seaborn.pydata.org/index.html).
        Документация к библиотеке seaborn, содержащая большое количество примеров.
    4. [Color Guide to Seaborn Palettes]
    (medium.com/@morganjonesartist/color-guide-to-seaborn-palettes-da849406d44f).
        Небольшая статья с Medium, в которой автор не только перечисляет все возможные
        палитры цветов для использования в seaborn, но еще и строит графики
        с их использованием, чтобы можно было сразу решить, что вы хотите
        использовать в собственных визуализациях.
    5. [Plotly Open Source Python Library](plotly.com/python/).
        Документация к библиотеке Plotly. Несколько запутанная, но зато снабженная 
        огромным количеством живых примеров.

    6. [Pandas Profiling](github.com/pandas-profiling/pandas-profiling).
        Ссылка на гитхаб проекта. Там можно посмотреть, как эта популярная 
        библиотека реализована изнутри.
    """)
コード例 #6
0
import torch
from src.net import Net
import json
import argparse
from src.load_dataset import load_dataset

PATH = './model.pth'
class_map = {
    0: 'female',
    1: 'male',
}

parser = argparse.ArgumentParser()
parser.add_argument('path', type=str)
args = parser.parse_args()

net = Net()
net.load_state_dict(torch.load(PATH))

loader, names = load_dataset(args.path)
predicted_general = []
for images in loader:
    outputs = net(images)
    _, predicted = torch.max(outputs, 1)
    predicted_general += predicted.tolist()

data = {names[i]: class_map[predicted_general[i]] for i in range(len(names))}

with open('process_results.json', 'w') as outfile:
    json.dump(data, outfile)
コード例 #7
0
def main():

    # args = parser.parse_args()
    args = Opts()
    enc = encoder.get_encoder(args.model_name)
    hparams = model.default_hparams()

    with open(os.path.join('models', args.model_name, 'hparams.json')) as f:
        # hparams.override_from_dict(json.load(f))
        hparams.override_from_dict(json.loads(f.read()))

    if args.sample_length > hparams.n_ctx:
        raise ValueError("Can't get samples longer than window size: %s" %
                         hparams.n_ctx)

    if args.model_name == '345M':
        args.memory_saving_gradients = True
        if args.optimizer == 'adam':
            args.only_train_transformer_layers = True

    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.graph_options.rewrite_options.layout_optimizer = rewriter_config_pb2.RewriterConfig.OFF
    with tf.Session(config=config) as sess:
        context = tf.placeholder(tf.int32, [args.batch_size, None])
        context_in = randomize(context, hparams, args.noise)
        output = model.model(hparams=hparams, X=context_in)
        loss = tf.reduce_mean(
            tf.nn.sparse_softmax_cross_entropy_with_logits(
                labels=context[:, 1:], logits=output['logits'][:, :-1]))

        if args.val_every > 0:
            val_context = tf.placeholder(tf.int32, [args.val_batch_size, None])
            val_output = model.model(hparams=hparams, X=val_context)
            val_loss = tf.reduce_mean(
                tf.nn.sparse_softmax_cross_entropy_with_logits(
                    labels=val_context[:, 1:],
                    logits=val_output['logits'][:, :-1]))
            val_loss_summary = tf.summary.scalar('val_loss', val_loss)

        tf_sample = sample.sample_sequence(hparams=hparams,
                                           length=args.sample_length,
                                           context=context,
                                           batch_size=args.batch_size,
                                           temperature=1.0,
                                           top_k=args.top_k,
                                           top_p=args.top_p)

        all_vars = [v for v in tf.trainable_variables() if 'model' in v.name]
        train_vars = [v for v in all_vars if '/h' in v.name
                      ] if args.only_train_transformer_layers else all_vars

        if args.optimizer == 'adam':
            opt = tf.train.AdamOptimizer(learning_rate=args.learning_rate)
        elif args.optimizer == 'sgd':
            opt = tf.train.GradientDescentOptimizer(
                learning_rate=args.learning_rate)
        else:
            exit('Bad optimizer:', args.optimizer)

        if args.accumulate_gradients > 1:
            if args.memory_saving_gradients:
                exit(
                    "Memory saving gradients are not implemented for gradient accumulation yet."
                )
            opt = AccumulatingOptimizer(opt=opt, var_list=train_vars)
            opt_reset = opt.reset()
            opt_compute = opt.compute_gradients(loss)
            opt_apply = opt.apply_gradients()
            summary_loss = tf.summary.scalar('loss', opt_apply)
        else:
            if args.memory_saving_gradients:
                opt_grads = memory_saving_gradients.gradients(loss, train_vars)
            else:
                opt_grads = tf.gradients(loss, train_vars)
            opt_grads = list(zip(opt_grads, train_vars))
            opt_apply = opt.apply_gradients(opt_grads)
            summary_loss = tf.summary.scalar('loss', loss)

        summary_lr = tf.summary.scalar('learning_rate', args.learning_rate)
        summaries = tf.summary.merge([summary_lr, summary_loss])

        summary_log = tf.summary.FileWriter(
            os.path.join(CHECKPOINT_DIR, args.run_name))

        saver = tf.train.Saver(var_list=all_vars,
                               max_to_keep=5,
                               keep_checkpoint_every_n_hours=2)
        sess.run(tf.global_variables_initializer())

        if args.restore_from == 'latest':
            ckpt = tf.train.latest_checkpoint(
                os.path.join(CHECKPOINT_DIR, args.run_name))
            if ckpt is None:
                # Get fresh GPT weights if new run.
                ckpt = tf.train.latest_checkpoint(
                    os.path.join('models', args.model_name))
        elif args.restore_from == 'fresh':
            ckpt = tf.train.latest_checkpoint(
                os.path.join('models', args.model_name))
        else:
            ckpt = tf.train.latest_checkpoint(args.restore_from)
        print('Loading checkpoint', ckpt)
        saver.restore(sess, ckpt)

        print('Loading dataset...')
        chunks = load_dataset(enc,
                              args.dataset,
                              args.combine,
                              encoding=args.encoding)
        data_sampler = Sampler(chunks)
        if args.val_every > 0:
            if args.val_dataset:
                val_chunks = load_dataset(enc,
                                          args.val_dataset,
                                          args.combine,
                                          encoding=args.encoding)
            else:
                val_chunks = chunks
        print('dataset has', data_sampler.total_size, 'tokens')
        print('Training...')

        if args.val_every > 0:
            # Sample from validation set once with fixed seed to make
            # it deterministic during training as well as across runs.
            val_data_sampler = Sampler(val_chunks, seed=1)
            val_batches = [[
                val_data_sampler.sample(1024)
                for _ in range(args.val_batch_size)
            ] for _ in range(args.val_batch_count)]

        counter = 1
        counter_path = os.path.join(CHECKPOINT_DIR, args.run_name, 'counter')
        if os.path.exists(counter_path):
            # Load the step number if we're resuming a run
            # Add 1 so we don't immediately try to save again
            with open(counter_path, 'r') as fp:
                counter = int(fp.read()) + 1

        def save():
            maketree(os.path.join(CHECKPOINT_DIR, args.run_name))
            print(
                'Saving',
                os.path.join(CHECKPOINT_DIR, args.run_name,
                             'model-{}').format(counter))
            saver.save(sess,
                       os.path.join(CHECKPOINT_DIR, args.run_name, 'model'),
                       global_step=counter)
            with open(counter_path, 'w') as fp:
                fp.write(str(counter) + '\n')

        def generate_samples():
            print('Generating samples...')
            context_tokens = data_sampler.sample(1)
            all_text = []
            index = 0
            while index < args.sample_num:
                out = sess.run(
                    tf_sample,
                    feed_dict={context: args.batch_size * [context_tokens]})
                for i in range(min(args.sample_num - index, args.batch_size)):
                    text = enc.decode(out[i])
                    text = '======== SAMPLE {} ========\n{}\n'.format(
                        index + 1, text)
                    all_text.append(text)
                    index += 1
            print(text)
            maketree(os.path.join(SAMPLE_DIR, args.run_name))
            with open(os.path.join(SAMPLE_DIR, args.run_name,
                                   'samples-{}').format(counter),
                      'w',
                      encoding=args.encoding) as fp:
                fp.write('\n'.join(all_text))

        def validation():
            print('Calculating validation loss...')
            losses = []
            for batch in tqdm.tqdm(val_batches):
                losses.append(
                    sess.run(val_loss, feed_dict={val_context: batch}))
            v_val_loss = np.mean(losses)
            v_summary = sess.run(val_loss_summary,
                                 feed_dict={val_loss: v_val_loss})
            summary_log.add_summary(v_summary, counter)
            summary_log.flush()
            print('[{counter} | {time:2.2f}] validation loss = {loss:2.2f}'.
                  format(counter=counter,
                         time=time.time() - start_time,
                         loss=v_val_loss))

        def sample_batch():
            return [data_sampler.sample(1024) for _ in range(args.batch_size)]

        avg_loss = (0.0, 0.0)
        start_time = time.time()

        try:
            while True:
                if counter % args.save_every == 0:
                    save()
                if counter % args.sample_every == 0:
                    generate_samples()
                if args.val_every > 0 and (counter % args.val_every == 0
                                           or counter == 1):
                    validation()

                if args.accumulate_gradients > 1:
                    sess.run(opt_reset)
                    for _ in range(args.accumulate_gradients):
                        sess.run(opt_compute,
                                 feed_dict={context: sample_batch()})
                    (v_loss, v_summary) = sess.run((opt_apply, summaries))
                else:
                    (_, v_loss, v_summary) = sess.run(
                        (opt_apply, loss, summaries),
                        feed_dict={context: sample_batch()})

                summary_log.add_summary(v_summary, counter)

                avg_loss = (avg_loss[0] * 0.99 + v_loss,
                            avg_loss[1] * 0.99 + 1.0)

                print(
                    '[{counter} | {time:2.2f}] loss={loss:2.2f} avg={avg:2.2f}'
                    .format(counter=counter,
                            time=time.time() - start_time,
                            loss=v_loss,
                            avg=avg_loss[0] / avg_loss[1]))

                counter += 1
        except KeyboardInterrupt:
            print('interrupted')
            save()
コード例 #8
0
ファイル: model.py プロジェクト: LoveSolaristics/Easy-ML
def model_app(prev_vars=None):
    dataset = load_dataset()
    dataset_columns = list(dataset.columns)
    numeric_columns = dataset.select_dtypes(include=np.number).columns.tolist()

    st.markdown("""
    # Обучение моделей

    Многие задачи, решаемые с помощью ML, относятся к одной из двух следующих категорий:

    1. Задача регрессии – прогноз на основе выборки объектов с различными признаками. 
    На выходе должно получиться вещественное число (2, 35, 76.454 и др.), 
    к примеру цена квартиры, стоимость ценной бумаги по прошествии полугода, 
    ожидаемый доход магазина на следующий месяц, качество вина при слепом тестировании.
    2. Задача классификации – получение категориального ответа на основе набора признаков. 
    Имеет конечное количество ответов (как правило, в формате «да» или «нет»): 
    есть ли на фотографии кот, является ли изображение человеческим лицом, болен ли пациент раком.

    Про другие можно прочесть, например, в [статье](habr.com/ru/post/448892/) на Хабре.
    Инструменты, представленные на этой странице позволяют быстро проверить, как реализуют
    себя те или иные алгоритмы на данных, представленных в датасете. То есть вы можете сказать, 
    значения в каком столбце нужно предсказать, данные разобъются на тренировочную и 
    тестовую выборки, модель обучится, предскажет значения на тестовой выборке, а на выходе
    можно будет узнать успешность предсказания, используя нужную метрику.

    Выберите задачу, которая стоит перед вами: классификация или регрессия.
    """)

    task = st.selectbox('Задача', [' ', 'Классификация', 'Регрессия'])

    if task == 'Классификация':
        classification_target = st.selectbox(
            'Выберите колонку, значения которой будем предсказывать',
            [None] + dataset_columns)

        if classification_target is None:
            st.info(
                'Выберите target. Для стандартного датасета следует выбрать столбец Survived.'
            )
        else:
            with st.expander('Дополнительные настройки классификации'):
                classification_test_size = st.slider(
                    'Размер тестовой выборки от всего '
                    'объема датасета',
                    min_value=0.1,
                    max_value=0.5,
                    step=0.05,
                    value=0.3)

                features = numeric_columns
                if classification_target in features:
                    features.remove(classification_target)
                classification_features = st.multiselect(
                    'Признаки, используемые для классификации',
                    features,
                    default=features)

                classification_random_state = st.selectbox(
                    'Хотите, чтобы при перезапуске программа '
                    'выдавала те же значения?', [False, True])
                if classification_random_state:
                    classification_random_state = 17
                else:
                    classification_random_state = None

                models = {
                    "Nearest Neighbors":
                    KNeighborsClassifier(3),
                    "Linear SVM":
                    SVC(kernel="linear", C=0.025, probability=True),
                    "RBF SVM":
                    SVC(gamma=2, C=1, probability=True),
                    "Gaussian Process":
                    GaussianProcessClassifier(1.0 * RBF(1.0)),
                    "Decision Tree":
                    DecisionTreeClassifier(max_depth=5),
                    "Random Forest":
                    RandomForestClassifier(max_depth=5,
                                           n_estimators=10,
                                           max_features=1),
                    "Neural Net":
                    MLPClassifier(alpha=1, max_iter=1000),
                    "AdaBoost":
                    AdaBoostClassifier(),
                    "Naive Bayes":
                    GaussianNB(),
                    "QDA":
                    QuadraticDiscriminantAnalysis()
                }

                classification_model_name = st.selectbox(
                    'Выберите модель классификации', list(models.keys()))

            if st.button('Обучить модель', key='model_button'):
                df = dataset.dropna()

                X = df[classification_features]
                y = df[classification_target]

                X_train, X_test, y_train, y_test = train_test_split(
                    X,
                    y,
                    test_size=classification_test_size,
                    random_state=classification_random_state)

                model = models[classification_model_name]
                model.fit(X_train, y_train)

                def plot_confusion_matrix(cm,
                                          classes,
                                          normalize=False,
                                          title='Матрица ошибок'):

                    plt.imshow(cm, interpolation='nearest', cmap='Blues')
                    plt.title(title)
                    plt.colorbar()
                    tick_marks = np.arange(len(classes))
                    plt.xticks(tick_marks, classes, rotation=45)
                    plt.yticks(tick_marks, classes)

                    if normalize:
                        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
                        st.info("Построена ормализованная матрица ошибок")
                    else:
                        st.info('Построена матрица ошибок без нормализации')

                    thresh = cm.max() / 2.
                    for i, j in product(range(cm.shape[0]),
                                        range(cm.shape[1])):
                        plt.text(
                            j,
                            i,
                            cm[i, j],
                            horizontalalignment="center",
                            color="white" if cm[i, j] > thresh else "black")

                    plt.tight_layout()
                    plt.ylabel('Истинные метки класса')
                    plt.xlabel('Предсказанные метки класса')

                font = {'size': 15}
                plt.rc('font', **font)
                plt.figure(figsize=(10, 8))

                cnf_matrix = confusion_matrix(y_test, model.predict(X_test))

                st.markdown("""
                ## Матрица ошибок

                Перед переходом к самим метрикам необходимо ввести важную концепцию для описания 
                этих метрик в терминах ошибок классификации — confusion matrix (матрица ошибок).
                Допустим, что у нас есть два класса и алгоритм, предсказывающий принадлежность 
                каждого объекта одному из классов, тогда матрица ошибок классификации будет 
                выглядеть следующим образом:

                <table style="margin: 10px auto">
                  <tr>
                    <td></td>
                    <td>y = 0</td>
                    <td>y = 1</td>
                  </tr>
                  <tr>
                    <td>y' = 1</td>
                    <td>True Positive (TP)</td>
                    <td>False Positive (FP)</td>
                  </tr>
                  <tr>
                    <td>y' = 0</td>
                    <td>False Negative (FN)</td>
                    <td>True Negative (TN)</td>
                  </tr>
                </table>

                Здесь y' — это ответ алгоритма на объекте, а y — истинная метка класса 
                на этом объекте. Таким образом, ошибки классификации бывают двух видов: 
                False Negative (FN) и False Positive (FP).
                """,
                            unsafe_allow_html=True)

                plot_confusion_matrix(cnf_matrix,
                                      classes=['Non-churned', 'Churned'],
                                      title='Матрица ошибок')

                st.pyplot(plt)

                st.markdown("""
                ## Precision, recall и F-мера

                Для оценки качества работы алгоритма на каждом из классов по отдельности 
                введем метрики $precision$ (точность) и $recall$ (полнота).

                """)
                st.latex(r'precision = \frac{TP}{TP + FP}')
                st.latex(r'recall = \frac{TP}{TP + FN}')

                st.markdown("""
                $Precision$ можно интерпретировать как долю объектов, названных классификатором 
                положительными и при этом действительно являющимися положительными, 
                а $recall$ показывает, какую долю объектов положительного класса из всех 
                объектов положительного класса нашел алгоритм.

                Именно введение $precision$ не позволяет нам записывать все объекты в один класс, 
                так как в этом случае мы получаем рост уровня False Positive. 
                $Recall$ демонстрирует способность алгоритма обнаруживать данный класс вообще, 
                а $precision$ — способность отличать этот класс от других классов.

                Обычно при оптимизации гиперпараметров алгоритма (например, в случае перебора по 
                сетке `GridSearchCV` ) используется одна метрика, улучшение которой мы и ожидаем 
                увидеть на тестовой выборке.

                Существует несколько различных способов объединить precision и recall в 
                агрегированный критерий качества. $F-мера$ (в общем случае $F_β$) — среднее 
                гармоническое $precision$ и $recall$:
                """)

                st.latex(
                    r"F_β = (1 + \beta^2) \cdot \frac{precision \cdot recall}"
                    r"{(β^2 \cdot precision) + recall}")

                st.markdown(
                    """$β$ в данном случае определяет вес точности в метрике, и при $β=1$ 
                это среднее гармоническое (с множителем 2, чтобы в случае 
                $precision=1$ и $recall=1$ иметь $F_1=1$). 
                $F-мера$ достигает максимума при полноте и точности, равными единице, 
                и близка к нулю, если один из аргументов близок к нулю.
                В `sklearn` есть удобная функция `metrics.classification_report`, 
                возвращающая $recall$, $precision$ и $F-меру$ для каждого из классов, 
                а также количество экземпляров каждого класса.
                """)

                report = classification_report(y_test, model.predict(X_test))
                st.code('Classification report:\n\n' + report)

                st.markdown("""
                ## ROC-кривая

                При конвертации вещественного ответа алгоритма (как правило, вероятности 
                принадлежности к классу, отдельно см. SVM) в бинарную метку, мы должны выбрать 
                какой-либо порог, при котором 0 становится 1. Естественным и близким кажется порог, 
                равный 0.5, но он не всегда оказывается оптимальным, например,
                отсутствии баланса классов.

                Одним из способов оценить модель в целом, не привязываясь к конкретному порогу, 
                является AUC-ROC (или ROC AUC) — площадь (Area Under Curve) под кривой ошибок 
                (Receiver Operating Characteristic curve ). Данная кривая представляет из себя 
                линию от (0,0) до (1,1) в координатах True Positive Rate (TPR) и False Positive 
                Rate (FPR):
                """)

                st.latex(r"TPR=\frac{TP}{TP + FN}")
                st.latex(r"FPR=\frac{FP}{FP + TN}")

                st.write(
                    """TPR нам уже известна, это полнота, а FPR показывает, какую долю из 
                объектов negative класса алгоритм предсказал неверно. В идеальном случае, 
                когда классификатор не делает ошибок (FPR = 0, TPR = 1) мы получим площадь под 
                кривой, равную единице; в противном случае, когда классификатор случайно выдает 
                вероятности классов, AUC-ROC будет стремиться к 0.5, так как классификатор будет 
                выдавать одинаковое количество TP и FP.
                Каждая точка на графике соответствует выбору некоторого порога. Площадь под 
                кривой в данном случае показывает качество алгоритма (больше — лучше), кроме этого, 
                важной является крутизна самой кривой — мы хотим максимизировать TPR, минимизируя 
                FPR, а значит, наша кривая в идеале должна стремиться к точке (0,1).
                """)

                sns.set(font_scale=1.5)
                sns.set_color_codes("muted")

                plt.figure(figsize=(10, 8))

                fpr, tpr, thresholds = roc_curve(
                    y_test, model.predict_proba(X_test)[:, 1], pos_label=1)

                lw = 2
                plt.plot(fpr, tpr, lw=lw, label='ROC curve')
                plt.plot([0, 1], [0, 1])
                plt.xlim([0.0, 1.0])
                plt.ylim([0.0, 1.05])
                plt.xlabel('False Positive Rate')
                plt.ylabel('True Positive Rate')
                plt.title('ROC-кривая')
                st.pyplot(plt)
                # TODO:
                #  разобраться с предупреждением
                #  UndefinedMetricWarning: No positive samples in y_true, true positive value
                #  should be meaningless на Ирисах Фишера

                st.markdown("""
                Критерий AUC-ROC устойчив к несбалансированным классам 
                (спойлер: увы, не всё так однозначно) и может быть интерпретирован как вероятность 
                того, что случайно выбранный positive объект будет проранжирован классификатором 
                выше (будет иметь более высокую вероятность быть positive), чем случайно выбранный 
                negative объект.
                """)

                st.markdown("""
                ## Полезные ссылки

                Разумеется здесь рассморены не все возможные метрики в задаче классификации, 
                например, "забыли" про банальный accuracy из-за плохой интерпретируемости
                результатов, а также не рассмотрели, к примеру, logic loss. Но в один текст это
                всё не уместишь, поэтому ниже ссылки для дальнейшего ознакомления:

                1. [Classifier comparison](
                scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html)
                . Примеры классификаторов из библиотеки `sklearn` с красивыми графиками.
                2. [Метрики в задачах машинного обучения]
                (habr.com/ru/company/ods/blog/328372/). Текст о метриках в основном взят
                именно оттуда. 
                3. [Metrics and scoring: quantifying the quality of predictions]
                (scikit-learn.org/stable/modules/model_evaluation.html). Очередная ссылка
                на документацию `sklearn`, но на этот раз на страницу, где подробнее говорится о 
                метриках.
                """)

    elif task == 'Регрессия':
        regression_target = st.selectbox(
            'Выберите колонку, значения которой будем предсказывать',
            [None] + numeric_columns)

        if regression_target is None:
            st.info(
                'Выберите target. Для стандартного датасета следует выбрать столбец Survived.'
            )
        else:
            with st.expander('Дополнительные настройки регрессии'):
                regression_n_splits = st.slider('Кроличество разбиений',
                                                min_value=5,
                                                max_value=20,
                                                step=1,
                                                value=10)

                features = numeric_columns
                if regression_target in features:
                    features.remove(regression_target)
                regression_features = st.multiselect(
                    'Признаки, используемые для классификации',
                    features,
                    default=features)

                regression_random_state = st.selectbox(
                    'Хотите, чтобы при перезапуске программа '
                    'брала на train и test те же данные?', [False, True])
                if regression_random_state:
                    regression_random_state = 17
                else:
                    regression_random_state = None

                models = {
                    "Linear Regression": LinearRegression(),
                    "Ridge": Ridge(),
                    "Lasso": Lasso(),
                    "ElasticNet": ElasticNet(),
                    "KNeighborsRegressor": KNeighborsRegressor(),
                    "Decision TreeRegressor": DecisionTreeRegressor(),
                    "SVR": SVR()
                }

                regression_model_name = st.selectbox(
                    'Выберите модель классификации', list(models.keys()))

                metrics = {
                    "Средняя абсолютная ошибка (MAE)":
                    'neg_mean_absolute_error',
                    "Средняя квадратическая ошибка (MSE)":
                    'neg_mean_squared_error',
                    "R Squared": 'r2'
                }

            if st.button('Обучить модель', key='model_button'):
                df = dataset.dropna()

                X = df[regression_features]
                y = df[regression_target]

                model = models[regression_model_name]

                kfold = KFold(n_splits=10,
                              random_state=regression_random_state)

                results = pd.DataFrame(columns=[
                    'Название метрики', 'Среднее значение',
                    'Стандартное отклонение'
                ])
                for metric_name, scoring in metrics.items():
                    result = cross_val_score(model,
                                             X,
                                             y,
                                             cv=kfold,
                                             scoring=scoring)
                    results = results.append(
                        {
                            'Название метрики': metric_name,
                            'Среднее значение': result.mean(),
                            'Стандартное отклонение': result.std()
                        },
                        ignore_index=True)

                st.markdown("""
                В этом разделе будут рассмотрены 3 наиболее распространенных показателя для оценки 
                прогнозов проблем регрессионного машинного обучения:

                1. Средняя абсолютная ошибка.
                2. Средняя квадратичная ошибка
                3. $R^2$.

                ## Средняя абсолютная ошибка
                Средняя абсолютная ошибка (или MAE) представляет собой сумму абсолютных различий 
                между прогнозами и фактическими значениями. Это дает представление о том, 
                насколько неправильными были прогнозы.

                Мера дает представление о величине ошибки, но не дает представление о
                направлении. То есть при определении скорости машины мы могли ошибиться на 20 км/ч,
                но сказать, двигался ли автомобиль медленне или быстрее предсказанного не смогли бы.

                ## Средняя квадратическая ошибка

                Средняя квадратическая ошибка (или MSE) очень похожа на среднюю абсолютную 
                ошибку в том, что она дает общее представление о величине ошибки.

                Взятие квадратного корня из среднеквадратичной ошибки преобразует единицы обратно 
                в исходные единицы выходной переменной и может иметь смысл для описания и 
                представления. Это называется среднеквадратической ошибкой (или RMSE).

                ## Метрика $R ^ 2$

                Метрика $R ^ 2$ (или R Squared) указывает на достоверность соответствия набора 
                прогнозов фактическим значениям. В статистической литературе эта мера называется 
                коэффициентом детерминации.

                Это значение между 0 и 1 для неподходящего и идеального соответствия соответственно.

                ## Оценка работы алгоритма

                Данные из датасета были разбиты на несколько частей определенное количество раз с
                помощью `sklearn.model_selection.cross_val_score` и `sklearn.model_selection.Kfold`,
                каждый раз после обучения модели был произведен рассчет трех вышеописанных метрик.
                Средний результат вы можете увидеть в таблице ниже:
                """)

                st.dataframe(results)

                st.markdown("""
                Также для наглядност построим scatterplot, чтобы понять, как результаты работы
                алгоритма отличаются от реальных. В идеальном случае точки должны лежать на одной 
                прямой, направленной под углом 45 градуусов.
                """)

                x, y = df[regression_features], df[regression_target]
                model = models[regression_model_name]
                model.fit(x, y)
                y_pred = model.predict(x)
                plt.scatter(y_pred, y)
                plt.title("Предсказание vs реальность")
                plt.xlabel("Предсказанные значения")
                plt.ylabel("Реальные значения")
                st.pyplot(plt)

                st.markdown("""
                ## Полезные ссылки

                1. [Документация о кросс-валидации] ( 
                scikit-learn.org/stable/modules/cross_validation.html). Здесь можно узнать больше 
                об уже упомянутом способе кросс-валидации, а также узнать, какие еще способы 
                существуют, и как их использовать. 
                2. [Статья о метриках в задачах классификации и регрессии]
                (machinelearningmastery.ru/metrics-evaluate-machine-learning-algorithms-python/). 
                Короткая обзорная статья с примерами кода для новичков. 
                3. [MachineLearning.ru](
                machinelearning.ru/wiki/index.php?title=Заглавная_страница). 
                Профессиональный информационно-аналитический ресурс, посвященный
                машинному обучению, распознаванию образов и интеллектуальному анализу данных. 
                4. [Разбор задачи регрессии на примере датасета Boston](
                kaggle.com/shreayan98c/boston-house-price-prediction/data?select=housing.csv)
                """)

    else:
        st.info('Выберите задачу для продолжения')
コード例 #9
0
ファイル: data.py プロジェクト: LoveSolaristics/Easy-ML
def data_app(prev_vars=None):
    dataset = load_dataset()
    st.title('Просмотр датасета через Pandas')

    st.markdown("""
    Содержание:\n
    1. <a href='#part1.1'>Сэмпл данных</a>
    2. <a href='#part1.2'>Информация о датасете</a>
    3. <a href='#part1.3'>Таблица с отфильтрованными значениями</a>
    4. <a href='#part1.4'>Полезные ссылочки</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Прежде чем пытаться визуализировать данных, используя графики, и строить какие-либо модели
    необходимо просто напросто понять, что за данные входят в датасет.

    Для этого стоит взглянуть на конкретные строки таблицы с данными, чтобы понимать,
    в каком форме представлены данные, что можно распарсить, как можно получить
    дополнительные признаки. Всё это легко осуществить с помощью библиотеки `pandas`.
    """)

    st.markdown("""
    ## <a id='part1.1'>Сэмпл данных</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Прежде всего можно взять небольшую произвольную часть данных и посмотреть, как она выглядит.
    Для этого используется метод `pandas.DataFrame.sample`
    """)

    sample_len = st.slider('Величина сэмпла', min_value=5, max_value=10, value=7)

    dataset_sample = dataset.sample(sample_len)
    st.dataframe(dataset_sample)

    if st.button('Обновить сэмпл'):
        dataset_sample = dataset.sample(sample_len)

    st.markdown("""
    ## <a id='part1.2'>Информация о датасете</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    Также бывает полезно взглянуть на то, какими типами представлены данные. 
    Для этого используется метод `pandas.DataFrame.info`. 

    Он выводит три столбца: названия колонок, количество ненулевых значений и их тип.
    """)

    buffer = io.StringIO()
    dataset.info(buf=buffer)
    st.text(buffer.getvalue())

    st.markdown("""
    ## <a id='part1.3'>Таблица с отфильтрованными значениями</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    С помощью специального синтаксиса, предоставляемого библиотекой `pandas` для класса `DataFrame`
    можно с легкостью выбрать строки, которые соответствуют тем или иным логическим значениям.
    Это круче, чем Excel-таблицы и SQL-запросы.

    Возьмем все столбцы с числами (`pandas.DataFrame._get_numeric_data` или более безопасно 
    `pandas.DataFrame.select_dtypes(include=np.number).columns.tolist()`), 
    сделаем для них слайдеры
    и отфильтруем строки, используя значения, введенные через них.
    """)

    numeric_columns = dataset.select_dtypes(include=np.number).columns.tolist()

    sliders = {}

    dataset_columns = list(dataset.columns)
    allowed_columns = st.multiselect('Выберите колонки для отображения', dataset_columns,
                                     default=dataset_columns)

    with st.expander('Ограничения для колонок'):
        for column in numeric_columns:
            sliders[column] = st.slider(column, min(dataset[column]), max(dataset[column]),
                                        (min(dataset[column]), max(dataset[column])))

    filtered_data = dataset.copy()
    for column in numeric_columns:
        filtered_data = filtered_data[(filtered_data[column] >= sliders[column][0]) &
                                      (filtered_data[column] <= sliders[column][1])]

    st.dataframe(filtered_data[allowed_columns])

    st.markdown("""
    ## <a id='part1.4'>Полезные ссылочки</a>
    """, unsafe_allow_html=True)

    st.markdown("""
    И под конец поделюсь ссылками на ресурсы, которые так или иначе были использованы 
    в процессе создания этой странички.

    1. [Pandas User Guide](pandas.pydata.org/docs/user_guide/index.html#user-guide). 
        Очевидно, что неотъемлемой частью использования библиотеки является
        заглядывание в её документацию. 
    2. [Data Analysis with pandas - 30 Days Of Python](youtu.be/g_rfQQC2BjA). Канал 
        хорошего специалиста по Python, у которго есть замечательные курсы на Udemy и информативные
        ролики на Youtube.
    3. [HSE: Наука о данных](math-info.hse.ru/2020-21/Наука_о_данных). Понятный курс для 
        непрограммистов, которым по долгу службы приходится использовать python для анализа данных.
    """)
コード例 #10
0
ファイル: blah.py プロジェクト: sonalif/gpt-2
from src import encoder
from src.load_dataset import load_dataset

enc = encoder.get_encoder('117M')
chunks = load_dataset(enc, 'run.txt', 30, encoding='utf-8')
print(chunks)
コード例 #11
0
ファイル: train.py プロジェクト: tanreinama/chord2melody
def main():
    args = parser.parse_args()

    if args.dataset == 'lpd_5':
        tracks = ['Drums', 'Piano', 'Guitar', 'Bass', 'Strings']
    elif args.dataset == 'lpd_17':
        tracks = ['Drums', 'Piano', 'Chromatic Percussion', 'Organ', 'Guitar', 'Bass', 'Strings', 'Ensemble', 'Brass', 'Reed', 'Pipe', 'Synth Lead', 'Synth Pad', 'Synth Effects', 'Ethnic', 'Percussive', 'Sound Effects']
    else:
        print('invalid dataset name.')
        exit()
    trc_len = len(tracks)
    note_size = 84
    time_note = note_size*trc_len + 1
    end_note = note_size*trc_len + 2
    hparams = HParams(**{
      "n_vocab": end_note+1,
      "n_ctx": 1024,
      "n_embd": 768,
      "n_head": 12,
      "n_layer": 12
    })

    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.gpu_options.visible_device_list = args.gpu
    config.graph_options.rewrite_options.layout_optimizer = rewriter_config_pb2.RewriterConfig.OFF
    with tf.Session(config=config) as sess:
        context = tf.placeholder(tf.int32, [args.batch_size, None])
        context_in = randomize(context, hparams, args.noise)
        output = model.model(hparams=hparams, X=context_in)
        loss = tf.reduce_mean(
            tf.nn.sparse_softmax_cross_entropy_with_logits(
                labels=context[:, 1:], logits=output['logits'][:, :-1]))

        train_vars = [v for v in tf.trainable_variables() if 'model' in v.name]

        opt = tf.train.AdamOptimizer(learning_rate=args.learning_rate)

        opt_grads = tf.gradients(loss, train_vars)
        opt_grads = list(zip(opt_grads, train_vars))
        opt_apply = opt.apply_gradients(opt_grads)
        summary_loss = tf.summary.scalar('loss', loss)

        summary_lr = tf.summary.scalar('learning_rate', args.learning_rate)
        summaries = tf.summary.merge([summary_lr, summary_loss])

        summary_log = tf.summary.FileWriter(
            os.path.join(CHECKPOINT_DIR, args.run_name))

        saver = tf.train.Saver(
            var_list=train_vars,
            max_to_keep=5,
            keep_checkpoint_every_n_hours=2)
        sess.run(tf.global_variables_initializer())

        if args.restore_from == 'latest':
            ckpt = tf.train.latest_checkpoint(
                os.path.join(CHECKPOINT_DIR, args.run_name))
            print('Loading checkpoint', ckpt)
            saver.restore(sess, ckpt)
        elif args.restore_from != 'fresh':
            ckpt = tf.train.latest_checkpoint(args.restore_from)
            print('Loading checkpoint', ckpt)
            saver.restore(sess, ckpt)

        print('Loading dataset...')
        chunks = load_dataset(args.input)
        data_sampler = Sampler(chunks)
        print('dataset has', data_sampler.total_size, 'tokens')
        print('Training...')

        counter = 1
        counter_path = os.path.join(CHECKPOINT_DIR, args.run_name, 'counter')
        if os.path.exists(counter_path):
            # Load the step number if we're resuming a run
            # Add 1 so we don't immediately try to save again
            with open(counter_path, 'r') as fp:
                counter = int(fp.read()) + 1

        def save():
            maketree(os.path.join(CHECKPOINT_DIR, args.run_name))
            print(
                'Saving',
                os.path.join(CHECKPOINT_DIR, args.run_name,
                             'model-{}').format(counter))
            saver.save(
                sess,
                os.path.join(CHECKPOINT_DIR, args.run_name, 'model'),
                global_step=counter)
            with open(counter_path, 'w') as fp:
                fp.write(str(counter) + '\n')

        def sample_batch():
            return [data_sampler.sample(1024) for _ in range(args.batch_size)]

        avg_loss = (0.0, 0.0)
        start_time = time.time()

        try:
            while True:
                if counter % args.save_every == 0:
                    save()
                (_, v_loss, v_summary) = sess.run(
                    (opt_apply, loss, summaries),
                    feed_dict={context: sample_batch()})

                summary_log.add_summary(v_summary, counter)

                avg_loss = (avg_loss[0] * 0.99 + v_loss,
                            avg_loss[1] * 0.99 + 1.0)

                print(
                    '[{counter} | {time:2.2f}] loss={loss:2.2f} avg={avg:2.2f}'
                    .format(
                        counter=counter,
                        time=time.time() - start_time,
                        loss=v_loss,
                        avg=avg_loss[0] / avg_loss[1]))

                counter += 1
        except KeyboardInterrupt:
            print('interrupted')
            save()