Приложение. Кому и для чего подходит данный курс?

Это курс для новичков или специалистов, теоретический или практический, в быстром темпе или медленном?

Здравствуйте и добро пожаловать на занятия по теме «Глубокое обучение с подкреплением: глубокое обучение на языке Python, часть 7».

Цель этой лекции – ответить на несколько часто получаемых мною вопросов о сложности данного курса и о том, куда он вписывается с точки зрения академических знаний, профессиональной сферы и практической применимости. Поэтому вместо того, чтобы вновь и вновь отвечать по отдельности, кажется более разумным создать эту лекцию, чтобы ответить одновременно всем. Многие теряются, поскольку это их первый курс по машинному обучению и они не понимают, как он вписывается в общую схему.

Этот курс имеет академическую или практическую направленность? Он для начинающих или для специалистов? Он идёт в быстром темпе или медленном?

  • Вначале я отвечу на второй вопрос – предназначен ли этот курс для начинающих или для специалистов. Любопытно, что сам по себе этот вопрос является и вопросом машинного обучения. Позвольте мне объяснить, почему. Одной из проблем обработки естественных языков является неоднозначность – когда кто-то произносит какие-то слова, эти слова могут означать разные вещи. Так получилось, что у меня есть несколько курсов по обработке естественных языков, так что над этой проблемой я задумываюсь частенько. При чём здесь это? При том, что когда мы используем слова «новичок» и «специалист», мы должны задать вопрос: новичок – с чьей точки зрения? И специалист – с точки зрения кого? Некоторые из вас могут полагать, что новичок – это случайный человек с улицы, который ничего не знает, но даже тут присутствует двусмысленность. Так, есть люди, которые, по сути, даже не умеют пользоваться компьютером, кроме как включить его, проверить электронную почту и зайти на сайт. Есть другие, которые являются специалистами в работе с Microsoft Office, знающие, как пользоваться компьютером и создать документ в Microsoft Word или электронную таблицу, но никогда прежде не занимавшиеся программированием. И есть те, кто являются очень хорошими разработчиками с большим опытом написания программ, но понятия не имеющие, что такое машинное обучение. Все эти люди – в некотором роде новички, однако каждому из них понадобилось бы проделать совершенно разную работу, чтобы подготовиться к данному курсу.

Та же ситуация со специалистами. Большинство людей полагают, что любой, кто знает больше их самих, является специалистом, хотя, конечно, сколько знаете вы и сколько знает кто-то другой – вещь относительная. Если вы умеете только подключить и использовать библиотеку Sci-Kit Learn, но ничего более, то можете показаться специалистом для человека, знающего только Excel, но будете новичком в глазах человека, прочитавшего книгу К. Бишопа «Распознавание образов и машинное обучение».

Таким образом, закрывая вопрос о том, предназначен ли этот курс для новичков или для специалистов, можно для начала утверждать, что сама его постановка вводит в заблуждение, поскольку «новичок» и «специалист» не являются чётко определёнными понятиями. Вместо этого мы должны вернуться назад к вопросу о том, какой конкретно набор навыков нужен, прежде чем браться за изучение этого курса. Естественно, это определяется необходимыми предпосылками, которые перечислены в описании курса. Ключевой здесь является точность вопроса, и он звучит так: «Какой точно набор навыков мне нужен, прежде чем браться за изучение этого курса?» Это куда лучше, чем неоднозначные понятия вроде «новичок» и «специалист».

Другое дело, что каждый по-своему будет оценивать свои собственные навыки, и с этим куда сложнее иметь дело. Конечно, я могу заявить, что для прохождения этого курса вы должны уметь писать код на языке Python, но будьте уверены, что существует огромная разница между теми, кто выучил только как выводить на экран надпись «Hello, world» и цикл for, и теми, кто работает в крупных финансовых учреждениях.

Однако даже у работников этих крупных финансовых учреждений могут быть большие отличия. Такие же большие отличия могут быть даже внутри вашего собственного коллектива. Я видел ребят с 15-летним опытом, которые работали хуже, чем парни с опытом меньше года! Так что даже если я скажу, что вам нужно уметь писать код на языке Python, всё равно среди тех, кто считает себя в этом знатоком, окажется большой разброс в навыках. Точно так же дела обстоят в глубоком обучении. Я могу сказать, что вы должны знать, как работают нейронные сети, однако существует большая разница между теми, кто способен написать код с нуля и имеет опыт их использования, и теми, кто лишь в течение нескольких часов просматривал видео в интернете. Если бы вам пришлось выбирать, кто из них лучше знает нейронные сети, вы бы кого выбрали? Таким образом, чтобы действительно ответить на этот вопрос, мы должны вернуться к самому курсу. Если я заявляю, что вы должны уметь писать код на языке Python, а вы утверждаете, что умеете, но не понимаете некоторых фрагментов кода этого курса, то проще всего предположить, что ваши навыки программирования на языке Python ещё не являются удовлетворительными, так что вам нужно усовершенствовать свои навыки написания кода на Python, задавая вопросы в разделе вопросов и ответов и предпринимая соответствующие усилия, чтобы заполнить пробелы в знаниях.

Я довольно часто встречаю людей, чересчур уверенных в своих силах, в то время как, к сожалению, в реальности существует огромная пропасть между тем, что, по их мнению, они знают, и тем, что они знают на самом деле. Забавно, что эти люди иногда заявляют, что данный курс требует наличия степени кандидата наук по математике! Уверяю вас, что в моих курсах нет никакой математики, требующей кандидатской степени, или что только кандидат наук может их понять. Мои курсы не требуют знаний математики, выходящих за пределы университетской программы. Некоторые иногда даже утверждают, что имеют степень кандидата наук и что всё равно курс слишком сложен. Это просто смешно, поскольку, по сути, перечёркивает их степень. Весь смысл получения научной степени – стать независимым исследователем, и если вы, как считается, находитесь на том уровне, чтобы выполнять независимые исследования, однако не способны понять что-то из университетского курса математики… Ну, это не очень хорошо.

По сути, это сводится к тому, что некоторые на самом деле пытаются сказать, что, мол, то, чего я не могу понять, – несущественно, а то, что я могу понять, – существенно. Отсюда следует вывод: то, чего я не могу понять, мне знать и не нужно. Можно легко понять, почему такие рассуждения опасны: если вы действительно верите, что всё, чего вы не знаете, не существенно, то вы никогда не научитесь чему-либо новому.

Это подводит нас к третьему вопросу: этот курс идёт в быстром темпе или медленном? Полагаю, вы видите, к чему я клоню: это ещё один пример неоднозначности. Быстро – для кого? Восприятие скорости темпа курса зависит от изучающего этот курс. Если кто-то соответствующим образом подготовлен, то для него всё будет как надо; если кто-то уже знает большинство разбираемых тем, то, вероятно, курс ему покажется чересчур медленным; если же некто не подготовился или у него неадекватное понимание необходимых предпосылок для курса, то курс покажется чересчур быстрым. Таким образом, если я ожидаю, что вы что-то знаете, а вы не знаете, то вам стоит оценить, что заставляет вас думать, будто курс идёт чересчур быстро.

Вот вам настоящая проверка. Если я заявляю, что нечто основывается на математическом анализе и теории вероятностей, а вы утверждаете, что знаете математический анализ и теорию вероятностей, но не понимаете основанный на них материал, то вы должны честно ответить себе на вопрос: действительно ли я понимаю математический анализ и теорию вероятностей? Или преподаватель изобрёл какой-то свой математический анализ и свою теорию вероятностей, которые я пока что не очень понимаю? Конечно же, последнее не очень правдоподобно. Куда вероятнее, что вы полагали, что знаете математический анализ и теорию вероятностей, тогда как на самом деле – нет.

Теперь перейдём к нашему первому вопросу: этот курс академический, для специалистов или практический?

  • Чтобы понять ответ, вы должны понимать, где обычно обучают машинному обучению и как ему обучают. Прежде всего отметим, что машинное обучение обычно преподаётся на старших курсах университетов и колледжей на специальностях «Программирование» и «Программная инженерия». Студенты этих специальностей уже изучали в течение первых двух или трёх лет университета дифференциальное и интегральное счисление одной и многих переменных, линейную алгебру, дифференциальные уравнения, теорию вероятности и математическую статистику, дискретную математику, программирование и, наверное, многое другое. Таким образом, к тому моменту, когда они добираются до третьего или четвёртого курса, они уже знают весь этот материал и готовы его использовать.

Обычно академический курс содержит целую библиотеку алгоритмов машинного обучения, в котором можно изучить метод k ближайших соседей, логистическую регрессию, кластеризацию методом k средних, метод главных компонент и так далее – всё в одном курсе. Как правило, на изучение одного алгоритма отводится одна лекция, то есть около двух часов, а всего может быть где-то 12 или, может, 20 лекций в семестре. Под изучением алгоритма тут понимается главным образом алгебраические и геометрические выкладки; в такого рода курсе, как правило, не занимаются программированием на компьютере. Если же вы в конце концов добираетесь до программирования, то, как правило, это является частью лабораторной работы, представляющей собой лишь очень малую часть курса по сравнению со всем остальным. Таким образом, это в основном теоретическая работа с уравнениями, их решением и их обсуждением. Эти уравнения, как правило, включают в себя теорию вероятностей и теорию информации, так что в вашем распоряжении оказывается два часа для изучения теории одного алгоритма, после чего, если есть работа по написанию кода (хотя обычно её нет), она выполняется в ваше свободное время. Сами же по себе лекции не включают в себя никакого написания кода.

Но с этими академическими курсами возникает даже ещё большая проблема и заключается она в следующем. Что, если оценки по ним будут очень низкими? Из всех 100% выставленных оценок низкими в среднем могут оказаться около 25 или даже 40 процентов, и вы можете подумать: «Ничего себе! Тут никто не справляется!». Разумеется, это не так, поскольку оценки сдвигаются, основываясь на среднем значении. В чём же действительная проблема? Множество людей спрашивает меня, почему бы мне не охватить все алгоритмы машинного обучения в одном крупном курсе, назвав тот просто «Машинным обучением». Ответ в том, что если вы будете пытаться овладеть слишком многим, то в конечном итоге сможете понять лишь 25% материала, что вполне ясно показывает уровень оценок. Как говорится, практика – критерий истинности; взглянем на курсы, где слушатели пытаются усвоить одновременно 10 различных алгоритмов, и посмотрим, каков же результат. А результат заключается в том, что они не понимают ни одного из них. Если вы пытаетесь понять слишком многое, вы в конце концов не поймёте ничего. Я же придерживаюсь точки зрения, согласно которой, если вы хотите пройти курс, то должны стремиться понять 100% материала. Каждый курс разбит на ряд соответствующих уровней в зависимости от сложности и рассматриваемой темы. Так, например, вы, как правило, можете изучать 1-ю часть математического анализа, посвящённую дифференциальному счислению, вторую часть, посвящённую интегральному счислению, и 3-ю, посвящённую счислению многих переменных. Но вы никогда не будете изучать всё это в одном огромном курсе «Математика», поскольку тут слишком много материала, чтобы понять его весь и сразу. Я же хочу, чтобы вы понимали 100% материала; даже 50 или 75 процентов, по моему мнению, недостаточно. Если вы поняли 75% материала курса, а следующий курс основывается на тех 25%, которые вы не поняли, то вы не сможете перейти на следующий этап.

Теперь посмотрим на всё это с другой стороны – с точки зрения того, что большинство считает «практическим» курсом. Я не считаю эти курсы практическими и позже объясню, почему, однако использую здесь слово «практический» в кавычках, поскольку именно на это будут ссылаться некоторые начинающие слушатели. Итак, как обычно проходит «практический» курс? Ну, начнём с того, что вас никогда не научат, как работает алгоритм, разве что в самых общих чертах, с применением метафор и аналогий. Так, например, предположим, что вы изучаете градиентный спуск. Преподаватель может привести аналогию в виде мяча, катящегося по склону. Некоторые неопытные слушатели могут сделать заключение: «Я понимаю, как мяч скатывается со склона, следовательно, я понимаю градиентный спуск». Однако они не понимают, как находить производные, пренебрегают пониманием того, как выбрать хорошее значение коэффициента обучения, и, что особенно важно, пренебрегают воплощением градиентного спуска в коде. Таким образом, совершенно неверно полагать, что если вы можете представить себе катящийся по склону мяч, то понимаете градиентный спуск. Почему так? Проблема в том, что каждый может представить мяч, скатывающийся со склона, – это могут представить даже ваши бабушка с дедушкой, не умеющие и компьютер включить. Так что не приравнивайте понимание аналогии с пониманием настоящей темы.

Чему ещё учат на этих «практических» курсах? Ещё на них учат подключаться к API или, другими словами, использовать библиотеку, написанную кем-то другим, что тоже не фонтан. Обычно это включает в себя написание лишь двух-трёх строк кода. Задайтесь вопросом: если машинное обучение сводится к написанию двух-трёх строк, то почему оно так важно в наши дни? И почему человечеству потребовались десятилетия, чтобы осознать его полезность? Разумеется, ответ заключается в том, что машинное обучение – это гораздо больше, чем две-три строки кода. Когда вы используете библиотеку глубокого обучения вроде Keras, вы не занимаетесь машинным обучением, а лишь пишете программу, используя интерфейс глубокого обучения. Более точным тут будет сказать «Я могу написать программу с помощью библиотек глубокого обучения», а не «Я действительно знаю глубокое обучение».

Однако некоторые из вас могут заявить: но на самом деле именно API мне и нужен, чтобы получить от него ответ; меня не интересует, как оно работает. Вот тут-то вы и сталкиваетесь с проблемой. Напомню, что помимо того, что «все данные одинаковы», ещё и «все интерфейсы машинного обучения одинаковы». Возникает вопрос: какой API выбрать, если все они одинаковы? Как сделать осмысленный выбор, какой лучше применить? Действительность такова, что если вы не знаете, как всё это работает, вы не сможете ответить на эти вопросы. Вот почему некоторые из этих так называемых «практических» курсов могут охватывать одновременно 20 алгоритмов – потому что на самом деле в них никогда не рассказывается, как работают эти алгоритмы. Поскольку API каждый раз один и тот же, очень легко лишь сделать одно и то же 20 раз, не напрягаясь по поводу тонкостей. Это даёт людям большую уверенность в своих силах, ведь они оказались в состоянии сделать одно и то же 20 раз. Однако так думать опасно, ведь при этом вы не понимаете, что в действительности вы выучили лишь одну вещь, просто повторили её 20 раз.

А что с профессиональной точки зрения? Иногда люди склонны верить, что в их профессиональной деятельности им придётся использовать скорее практические навыки, а знать, как работает модель машинного обучения, на самом деле не очень-то и нужно. Нужно лишь знать API. Однако в действительности всё сводится к настоящей сути вашей работы. Если вы обычный рядовой программист и хотите просто посмотреть, как модель машинного обучения будет работать с вашими данными, то будете использовать преимущественно уже созданные библиотеки – как я указывал ранее, это лишь две-три строки кода. Впрочем, это вовсе не означает, что вам не нужно владеть наработанными методами, уметь удостовериться, что не смешиваете проверочный набор с учебным, что выполняете корректную проверку и так далее. Когда же дело доходит до настройки модели, вы должны уметь вникать в детали и видеть, как можно изменять гиперпараметры и какие из них окажут наибольшее влияние. Таким образом, одно только знание, как использовать API, позволяет вам достичь лишь начального этапа, когда вы можете подставить свои данные, а код хотя бы написан без синтаксических ошибок и работает. Хотя, конечно же, работоспособный код  – это вовсе не обязательно правильный код.

С другой стороны находятся программисты и учёные, чья единственная работа заключается в машинном обучении. Эти ребята – эксперты в машинном обучении. Они знают математику от и до и имеют полноценное компьютерное образование. Таким образом, просто для того, чтобы суметь эффективно донести свои идеи, вы должны быть знакомы с теорией, а не просто как подключить API с помощью пары строк кода. Эти учёные создают пользовательские модели, на самом деле закапываясь в математику, чтобы не только использовать, но и изобретать что-то новое. А чтобы быть в состоянии изобрести что-либо, нужно действительно хорошо знать математику. То есть, если вы являетесь участником такого рода коллектива, вам недостаточно лишь знать, как написать пару строк кода; ваши умения должны быть намного большими. Таким образом, ваш теоретический багаж знаний должен быть очень серьёзным, чтобы вы были в состоянии эффективно общаться с другими учёными.

Однако многие заявляют: да я никогда и не хотел быть учёным, так что на самом деле мне всё равно, как работают эти алгоритмы. К сожалению, это весьма плохое отношение к своей работе. Предположим, к примеру, что я управляю бизнесом, а мой сотрудник, желая похвастаться, заявляет, что он изучает машинное обучение. Он утверждает: «Я прохожу онлайн-курс по машинному обучению, так что я стану в нём специалистом!» Однако его подход к машинному обучению состоит в том, чтобы учиться как можно меньше. Он говорит, что ему плевать на математику, ему нужен лишь практический материал и знать лишь самый минимум. И вот он заявляет мне, что его не интересует, как всё работает, он просто будет подключать какой-нибудь API, потому что его приятель сказал ему, что так можно. Как владельцу бизнеса мне совершенно не хочется, чтобы у меня работал такой парень. Я управляю бизнесом, который что-то продаёт; и жизнь самой компании, и благосостояние её сотрудников основаны на том, что наш продукт является как можно более качественным. Таким образом, если кто-либо придёт ко мне и заявит, что не хочет напрягаться, чтобы быть лучшим, а хочет лишь выполнять самый минимум, то мой ответ – я не хочу видеть такого человека в своём коллективе, он должен быть уволен. Так что будьте осторожны, если вы именно так подходите к машинному обучению – ни один предприниматель не захочет услыхать, что ваш подход заключается в выполнении самого минимума и игнорировании математики из-за того, что она, по вашему мнению, слишком сложная. Для предпринимателя это удручающая ситуация.

Теперь уже, возвращаясь к нашему первоначальному вопросу, вы, наверное, поняли ответ, какого рода этот курс. Его можно рассматривать как союз между двумя вышеописанными подходами. Мы охватываем всю математику и все выкладки, поскольку они очень важны, если вы хотите иметь возможность эффективно общаться с другими учёными, эффективно отлаживать свой код и изобретать новые подходы. Это и понимается под машинным обучением – настоящее знание машинного обучения, а не просто написание программы с помощью API. Таким образом, теоретическое обоснование очень важно. В то же время мы не собираемся знакомиться с 20 различными алгоритмами в одном курсе, поскольку, в отличие от типичного академического курса, который вы можете пройти, усвоив лишь 25% материала, этот курс структурирован таким образом, что если у вас есть пробелы в знаниях, вы не сможете перейти к следующему этапу. Тем более, что академические курсы содержат немного занятий по написанию кода (если вообще содержат), тогда как в данном курсе каждый изучаемый нами алгоритм будет воплощаться в коде. Мой девиз – если вы не можете воплотить его в коде, значит, вы его не понимаете. Вы можете делать вид, что понимаете, а когда вы рассуждаете, может показаться, будто вы понимаете, однако реализация в коде – вот истинная проверка. Это как экзамен по математике и написание сочинения. При написании сочинения вы можете ввести преподавателя в заблуждение, как будто что-то понимаете; однако на экзамене по математике ваши ответы либо верны, либо нет. В этом плане ваш код либо работает, либо нет, это чётко видно.

Что касается практической стороны, то мы охватываем и её – мы демонстрируем наши алгоритмы как на реальных данных вроде текста или изображений, так и на двумерных наборах данных, чтобы можно было наглядно увидеть результат работы алгоритма. Обе эти демонстрации важны. Тексты и изображения, вероятно, являются самыми практическими данными на свете; некоторые компании, стоящие миллиарды долларов, существуют и процветают благодаря способности работать с ними. Двумерные наборы данных не менее важны, поскольку только их мы, люди, и можем наглядно увидеть. В то же время мы не пытаемся делать вид, будто нам для практики нужны 20 различных наборов данных; вместо этого мы изучаем нечто куда более ценное – как использовать алгоритм для бесконечного количества наборов данных, ведь мы способны абстрактно уяснить идею о том, что все данные – одинаковы. Не забывайте, что компьютер видит лишь список чисел и понятия не имеет, что эти числа представляют – замеры высоты или пиксели изображения. И конечно же, получив разносторонний опыт – и в теории, и в коде, – а затем подставив данные в свою модель, вы становитесь разносторонним специалистом.

В заключение я хотел бы поставить последний вопрос: как все эти знания помогут лично вам? Почему понимание подхода, принятого в этом курсе, в целом улучшают ваши знания в машинном обучении?

Надеюсь, я дал вам самое общее представление. Вы можете оценить различные подходы людей с различным багажом знаний. Лица из академической среды обычно не видят, что делают другие, не входящие в академическую среду; те же, кто ненавидит математику, как правило, не видят, что делают те, кто её обожает. Вы же с высоты птичьего полёта можете оценить их всех. При изучении машинного обучения это поможет вам понять, с кем вы конкурируете при трудоустройстве, какую работу необходимо выполнять и какую подготовку необходимо получить. Если же вы набираете коллектив для машинного обучения, это поможет вам понять различия в подготовке отдельных лиц, которую нужно сравнить, чтобы понять их сильные и слабые стороны и на что они способны.

Доказательство, что нет разницы, использовать Jupyter Notebook или нет

Время от времени я получаю от слушателей странный вопрос: почему я не использую Jupyter Notebook? Позвольте мне объяснить, почему я считаю такой вопрос странным. Прежде всего моя позиция состоит в том, что он совершенно не нужен и что нет никакой разницы, использовать его или нет. Позвольте повториться: нет никакой разницы, использовать Jupyter Notebook или нет, разве что всё выглядит чуть по-другому или, другими словами, просто экран другого цвета – это совершенно очевидно. В данной лекции я покажу, что так и есть.

Одна из основных причин, по которой я недолюбливаю Jupyter Notebook, заключается в том, что слишком уж много слушателей понятия не имеют, как на самом деле работает Python. Если вы уверенно себя чувствуете только в Notebook, а когда видите код на языке Python в текстовом файле или где-либо ещё, то пугаетесь и теряетесь, – это очень нехорошо. Код на языке Python в текстовом файле совершенно идентичен тому, каким он мог бы быть в Notebook, так что в действительности пугаться тут нечему. Программисты, занятые реальной работой, в конечном итоге нуждаются в коде, который бы компилировался и выполнялся автоматически. Другими словами, ваш конечный код будет находиться в файле Python, который запускается сам по себе, без всякого Jupyter Notebook. Поэтому если вы питаете надежды использовать свои умения в настоящей работе, то вам стоило бы приучиться писать код на Python без Jupyter Notebook. Кроме того, вам следует хорошенько запомнить, что на самом деле нет никакой разницы между кодом, написанным в Jupyter Notebook, в IPython или в консоли.

Вот мой любимый пример, как можно использовать Python в «реальном мире». Допустим, вы пишете скрипт, который отправит вашему начальнику электронное письмо с сообщением, что вы опаздываете на работу. Допустим также, что вы хотите не отправлять это письмо вручную, а чтобы оно отправлялось автоматически в каждое пятничное утро, чтобы начальник не орал на вас за опоздание на работу после чересчур бурных вечеринок по четвергам. Это очень просто: нужно лишь создать на сервере так называемый файл crontab. В файле нужно написать код, указывающий, когда вы желаете, чтобы команда запускалась, а затем указать, какая именно команда должна запускаться, – это просто

Python <имя_скрипта>

Как видите, это так же просто, как запускать скрипт Python с командной строки.

Теперь каждую пятницу в 9:45 утра этот скрипт будет отправлять одно и то же электронное письмо вашему начальнику, в котором сообщается, что вы опаздываете. Но не будем отвлекаться. Вся суть в том, что в действительности для чего-нибудь подобного вам совершенно не нужен Jupyter Notebook!

Полагаю, единственным заметным преимуществом Jupyter Notebook является то, что мы можем видеть результаты промежуточных вычислений. Однако это мнимое преимущество, а вовсе не реальное, ведь вы можете делать совершенно то же самое, и не запуская Notebook. Для начала, я уверен, вы уже видели, что IPython также выводит на экран результаты после введения команды. IPython относится к так называемым REPL (read-eval-print loop), что переводится как «цикл чтение-вычисление-вывод». К ним относится Python, Ruby, PHP и любые другие языки. Ключевым здесь является слово «вывод». Почему так? Ну, одно из моих золотых правил по написанию и отладке кода звучит так: «Если сомневаешься – выводи на экран!» Даже не могу сказать, сколько раз мне задавали вопрос в разделе вопросов и ответов, когда на него можно было легко ответить, просто вставив оператор вывода на экран в существующий код.

Так или иначе, в чём смысл этого долгого обсуждения о распечатках? В том, что если вы полагаете, будто Jupyter Notebook – это единственная программа, которая может так делать, то вам необходимо чуточку расширить свой кругозор. На самом деле вы всегда должны так делать – если вы не используете большое количество операторов вывода во время написания кода, то вы работаете неправильно. Не забывайте, что программирование – это не философские рассуждения, а от вас не требуется «запускать» программу в голове. Это всё равно, что пытаться делить многозначные числа, держа в руках калькулятор. Просто выводя на экран значения, вы добьётесь повышения эффективности своей работы. Перестаньте пытаться угадать, что будет делать программа, – просто дайте ей самой показать вам, что она делает. Ключевой вывод из всего этого состоит в том, что вы всегда должны выводить значения на экран, а то, что Jupyter Notebook показывает результат работы каждого блока кода – это не просто приятный сюрприз.

Другой важный урок заключается в том, что если желаете использовать Jupyter Notebook, то абсолютно ничего не мешает вам так и делать. Другими словами, использование Jupyter Notebook на 100% совместимо со всем, что мы и так делаем. На самом деле, если помните, ваша задача в этих курсах – не просто запускать мой код, а писать свой собственный. И, разумеется, поскольку это ваш код, то можете писать его, как хотите, в том числе и с применением Jupyter Notebook. В оставшейся части этой лекции я докажу вам, что вы можете взять любую программу из репозитария курса, о которой известно, что она запускается с консоли (потому что я всегда демонстрирую их именно так), и покажу, что совершенно тот же код запускается и в Jupyter Notebook.

Допустим, мы находимся в папке numpy_class и нас интересует код файла classification_example.py. Как видите, сейчас прямо сейчас этот код у меня находится в текстовом редакторе. Если вы не в курсе, что такое текстовый редактор, то это просто программа, которая показывает содержимое текстового файла и позволяющая это содержимое изменять (редактировать) – идеальная программа для написания кода. Иногда, когда приходится писать на языках вроде Java или Swift, можно использовать IDE, но и это совершенно необязательно. Так, сейчас я предпочитаю писать код на Java в обычном текстовом редакторе вроде Sublime. В любом случае обычно нет нужны использовать IDE для написания кода на Python.

Теперь что касается Jupyter Notebook. Запустим его.

Мы запустили Jupyter Notebook. Обратите внимание, что запустили мы его в той же папке, что и соответствующий файл Python – это надо иметь в виду на будущее. В данный момент я собираюсь доказать, что всё содержимое файла Python работает в Notebook в точности так же, как и в консоли. Начнём с импорта библиотек:

from __future__ import print_function, division

from future.utils import iteritems

from builtins import range, input

# Note: you may need to update your version of future

# sudo pip install -U future

# just in case we need it

import numpy as np

# import the function that will get the data

# yes, sklearn comes with built-in datasets!

from sklearn.datasets import load_breast_cancer

Пока что всё нормально. Теперь загрузим данные:

data = load_breast_cancer()

Мы загрузили данные. Я не уверен в типе данных, но могу их проверить с помощью функции type. Так и сделаем:

type(data)

Получаем ответ: sklearn.utils.Bunch. Это и есть тип данных переменной data. Ранее, если помните, мы выполняли этот пример в IPython, но, как видите, в Jupyter Notebook результат остаётся тем же. В качестве альтернативы можно запустить этот же файл в консоли и добавить несколько операторов вывода, чтобы видеть те же строки, что и сейчас. Но я не буду подробно останавливаться на таких мелких деталях в оставшейся части примера, поскольку вы этот пример уже видели. Так что продолжим построчно проходить файл дальше.

Допустим, я хочу проверить ключи в переменной data

data.keys()

Неплохо. Теперь проверим форму атрибута переменной data:

data.data.shape

Тоже всё нормально. Проверим целевые переменные:

data.target

По-прежнему всё как ожидалось. А что с именами целевых переменных target_names?

data.target_names

Хорошо. А их форма? Должно быть 569.

data.target.shape

Так и есть. Проверим ещё названия признаков feature_names:

data.feature_names

По-прежнему всё то же самое. Выполним теперь разделение данных на учебный и проверочный наборы:

from sklearn.model_selection import train_test_split

# split the data into train and test sets

# this lets us simulate how our model will perform in the future

X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.33)

Теперь инициируем и подгоним нашу модель:

from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier()

model.fit(X_train, y_train)

Проверим оценки учебного и проверочного наборов:

model.score(X_train, y_train)

model.score(X_test, y_test)

А теперь посмотрим, как у нас получается делать новые прогнозы:

predictions = model.predict(X_test)

predictions

Как видите, если мы обращаемся к переменной, то результат на экран не выводится, а если к выражению – то выводится.

Есть и альтернативный способ вычисления точности прогнозов:

N = len(y_test)

np.sum(predictions == y_test) / N

И получаем тот же ответ, что и ранее.

У нас есть и другой пример, в котором можем использовать нейронную сеть для тех же целей. Создадим модель, обучим её и выведем оценку точности для учебного набора:

from sklearn.neural_network import MLPClassifier

# you’ll learn why scaling is needed in a later course

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

X_train2 = scaler.fit_transform(X_train)

X_test2 = scaler.transform(X_test)

model = MLPClassifier(max_iter=500)

model.fit(X_train2, y_train)

# evaluate the model’s performance

model.score(X_train2, y_train)

А теперь выведем на экран оценку проверочного набора:

model.score(X_test2, y_test)

Всё работает совершенно так же, как и без применения Jupyter Notebook.

Можно было сделать и по-другому: просто взять весь код целиком, вставить в Jupyter Notebook и запустить его. Это другой возможный для вас способ, однако его недостатком является то, что мы не можем видеть промежуточных результатов. Вновь-таки, для этого и существуют операторы вывода.

Какие выводы мы можем сделать из этого упражнения? Мы видим, что данный код в Jupyter Notebook работает в точности так же, как и где-либо ещё. Вот почему я всегда говорю, что код Python – он и есть код Python, где бы он ни был. Если вы хотите использовать Jupyter Notebook, чтобы запускать код этого курса, то вам абсолютно ничего не мешает так и делать.

Python 2 vs. Python 3

В заключение, целью которой является пояснение, что вы вольны в выборе версии Python для прохождения данного курса.

Одно замечание, прежде чем мы начнём. Несмотря на то, что я обновил весь код в репозитарии для работы с Python 3, вы по-прежнему должны использовать команду git pull, чтобы быть уверенными, что у вас последняя версия кода. Я знаю, что некоторые создают новые ветки в репозитарии и Github, однако я настоятельно рекомендую так не делать, если хотите по-прежнему с лёгкостью получать последние обновления. Если же у вас всё-таки есть ветка, задумайтесь о том, чтобы её убрать, или, по крайней мере, убедитесь, что часто вносите в неё последние обновления.

Многие полагают, что Python 3 – это новейшая версия Python и, следовательно, что все должны её использовать. Однако это очень узкий взгляд. Для начала отметим, что Python 3 на самом деле не такой уж и новый. В действительности на момент создания этой лекции (2018 год) Python 3 существует уже на протяжении 10 лет. Фактически Python 2.6 был выпущен в то же время, что и Python 3, так что Python 2.6 и Python 3.0 имеют одинаковый «возраст». Некоторые думают, что поскольку 3 – это больше чем 2, то надо использовать 3-ю версию. Конечно же, вы понимаете, что это несколько поверхностное обоснование.

Большая трудность заключается в том, что если вы стали сотрудником большой компании, использующей на данный момент Python и создававшей свои программные продукты много лет назад, то, вероятно, в ней используется Python 2, ведь в большой компании нелегко переписать всю базу кода – это может занять месяцы или годы. Ни одна здравомыслящая компания с оборотами в миллионы долларов в день не будет останавливать свою работу только чтобы поменять версию Python. Представьте своё решение, будь вы управляющим или владельцем бизнеса. Пусть у вас есть список заказов от клиентов, за выполнение которых они готовы хорошо заплатить. Итак у вас есть выбор: или ваши программисты работают над чем-то, что приносит деньги, или они работают над чем-то, что не только не приносит денег, но и наоборот, стоит вам самим денег, ведь программистам за работу надо платить. Какой будет ваш выбор? Большинство лично моих знакомых выбрали бы вариант продолжать зарабатывать деньги. Так что к худу или к добру, но многие по-прежнему пользуются Python 2, а это значит, что если вы станете сотрудником такой компании, то будете вынуждены изучать синтаксис Python 2 – у вас просто не будет другого выбора.

В то же время отличия между Python 2 и Python 3, как правило, весьма тривиальны. К примеру, вместо того, чтобы набрать print и пробел после него, теперь print работает наподобие функции, так что аргумент нужно заключать в скобки. Другой пример – мы используем идентификатор range вместо xrange. В обоих случаях возвращаются объекты-генераторы, а не списки. В Python 2 range возвращает список, что может быть неэффективно, а потому мы стараемся при использовании Python  2 его не использовать. В Python 2 в операции деления используется косая черта (/), что приводит к разным результатам в зависимости от аргументов. Так, например, если числитель и знаменатель являются целыми числами, что результат будет целым числом, но если хоть один аргумент будет вещественным числом, то и результат будет вещественным числом. То же самое происходит в языках наподобие C, так что это довольно типично. В Python 3 косая черта всегда означает деление вещественных чисел, так что даже если у вас и числитель, и знаменатель являются целыми числами, результат будет числом вещественным. Если же вам нужно целочисленное деление, то надо использовать двойную косую черту (//). Другие примеры приведены на моём сайте на странице

https://lazyprogrammer.me/python-2-to-3-tips

Разумеется, кроме вышеприведенных, вы можете встретиться и с другими часто встречающимися различиями. Если вы столкнулись с чем-то, что не работает, приглашаю воспользоваться разделом вопросов и ответов, поскольку это самое лучшее место для получения помощи. Впрочем, вероятнее всего, что помощь вам не понадобится, ведь изменения в 99% случаев тривиальны. Так что нет причин отчаиваться, если увидите, что рабочий код написан на Python 2, а не на Python 3. Скорее всего, понадобится изменить лишь несколько строк, чтобы исчезли сообщения об ошибке, а всё заработает в кратчайшие сроки.

Андрей Никитенко
Андрей Никитенко
Задать вопрос эксперту
Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: