1646297640
TBVaccine
TBVaccine is a utility that pretty-prints Python tracebacks. It automatically highlights lines you care about and deemphasizes lines you don't, and colorizes the various elements in a traceback to make it easier to parse.
Here are some screenshots. This is the before:
And this is the after:
If you add the hook or call TBVaccine in your code, it can also print all variables in each stack frame. That is, it turns this:
into this:
To install, use pip
:
pip install tbvaccine
You are done!
You can have TBVaccine insert itself all up in your system and stick its tentacles in all your libraries, like a cute, useful Cthulhu. That way, every single Python traceback in your system will be pretty. Just set the TBVACCINE environment variable to 1, and you're done.
E.g. for bash:
export TBVACCINE=1
Or fish:
set -x TBVACCINE=1
If you want to prettify tracebacks even when stderr is not a tty, set TBVACCINE_FORCE to 1:
export TBVACCINE=1
export TBVACCINE_FORCE=1
python -c '1/0' 2>&1 | cat # pretty!
NOTE: If you're on Ubuntu, you most likely have Apport installed, which overrides TBVaccine's hook with its own. To disable Apport for Python, delete a file named /etc/python<version>/sitecustomize.py
. Note that this will disable Apport for Python, and you won't be asked to submit info to Ubuntu when Python programs crash any more. For some, this is a good thing.
TBVaccine can be used from the command line several ways.:
python -m tbvaccine myscript.py
Or just pipe STDERR into it from the program you want to watch:
./myscript.py 2>&1 | tbvaccine
And all the tracebacks will now be pretty!
There are various ways to use TBVaccine as a Python library.
Initialize it like so:
from tbvaccine import TBVaccine
tbv = TBVaccine(
code_dir="/my/code/dir",
isolate=True
)
code_dir
marks the directory we code about. Files under that directory that appear in the traceback will be highlighted. If not passed, the current directory, as returned by os.getcwd()
will be used.
If isolate
is False
, all lines are colorized, and code_dir
is ignored.
If show_vars
is False
, variables will not be printed in each stack frame.
To use it in an except
block:
from tbvaccine import TBVaccine
try:
some_stuff()
except:
print(TBVaccine().format_exc())
To make it the default way of printing tracebacks, use add_hook()
(which also accepts any argument the TBVaccine
class does):
import tbvaccine
tbvaccine.add_hook(isolate=False)
1 / 0
Bam! Instant pretty tracebacks.
You can integrate TBVaccine with logging like so:
class TbVaccineFormatter(logging.Formatter):
def formatException(self, exc_info):
return TBVaccine(isolate=True).format_exc()
sh = logging.StreamHandler()
sh.setFormatter(TbVaccineFormatter('[%(levelname)s] %(asctime)s : %(message)s', '%Y-%m-%d %H:%M:%S'))
logger.addHandler(sh)
To configure TBVaccine, open its configuration file in ~/.config/tbvaccine/tbvaccine.cfg
(or your operating system's equivalent) and edit it. You can currently configure the color style there by specifying one of the Pygments styles <http://pygments.org/demo/6778888/?style=monokai>.
This library is still pretty new, please contribute patches if something doesn't work as intended, and also please tell your friends about it! Hopefully one day it will be implemented in the Python interpreters themselves.
-- Stavros
Author: Skorokithakis
Source Code: https://github.com/skorokithakis/tbvaccine
License: MIT License
1669003576
In this Python article, let's learn about Mutable and Immutable in Python.
Mutable is a fancy way of saying that the internal state of the object is changed/mutated. So, the simplest definition is: An object whose internal state can be changed is mutable. On the other hand, immutable doesn’t allow any change in the object once it has been created.
Both of these states are integral to Python data structure. If you want to become more knowledgeable in the entire Python Data Structure, take this free course which covers multiple data structures in Python including tuple data structure which is immutable. You will also receive a certificate on completion which is sure to add value to your portfolio.
Mutable is when something is changeable or has the ability to change. In Python, ‘mutable’ is the ability of objects to change their values. These are often the objects that store a collection of data.
Immutable is the when no change is possible over time. In Python, if the value of an object cannot be changed over time, then it is known as immutable. Once created, the value of these objects is permanent.
Objects of built-in type that are mutable are:
Objects of built-in type that are immutable are:
Object mutability is one of the characteristics that makes Python a dynamically typed language. Though Mutable and Immutable in Python is a very basic concept, it can at times be a little confusing due to the intransitive nature of immutability.
In Python, everything is treated as an object. Every object has these three attributes:
While ID and Type cannot be changed once it’s created, values can be changed for Mutable objects.
Check out this free python certificate course to get started with Python.
I believe, rather than diving deep into the theory aspects of mutable and immutable in Python, a simple code would be the best way to depict what it means in Python. Hence, let us discuss the below code step-by-step:
#Creating a list which contains name of Indian cities
cities = [‘Delhi’, ‘Mumbai’, ‘Kolkata’]
# Printing the elements from the list cities, separated by a comma & space
for city in cities:
print(city, end=’, ’)
Output [1]: Delhi, Mumbai, Kolkata
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(cities)))
Output [2]: 0x1691d7de8c8
#Adding a new city to the list cities
cities.append(‘Chennai’)
#Printing the elements from the list cities, separated by a comma & space
for city in cities:
print(city, end=’, ’)
Output [3]: Delhi, Mumbai, Kolkata, Chennai
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(cities)))
Output [4]: 0x1691d7de8c8
The above example shows us that we were able to change the internal state of the object ‘cities’ by adding one more city ‘Chennai’ to it, yet, the memory address of the object did not change. This confirms that we did not create a new object, rather, the same object was changed or mutated. Hence, we can say that the object which is a type of list with reference variable name ‘cities’ is a MUTABLE OBJECT.
Let us now discuss the term IMMUTABLE. Considering that we understood what mutable stands for, it is obvious that the definition of immutable will have ‘NOT’ included in it. Here is the simplest definition of immutable– An object whose internal state can NOT be changed is IMMUTABLE.
Again, if you try and concentrate on different error messages, you have encountered, thrown by the respective IDE; you use you would be able to identify the immutable objects in Python. For instance, consider the below code & associated error message with it, while trying to change the value of a Tuple at index 0.
#Creating a Tuple with variable name ‘foo’
foo = (1, 2)
#Changing the index[0] value from 1 to 3
foo[0] = 3
TypeError: 'tuple' object does not support item assignment
Once again, a simple code would be the best way to depict what immutable stands for. Hence, let us discuss the below code step-by-step:
#Creating a Tuple which contains English name of weekdays
weekdays = ‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’
# Printing the elements of tuple weekdays
print(weekdays)
Output [1]: (‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’)
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(weekdays)))
Output [2]: 0x1691cc35090
#tuples are immutable, so you cannot add new elements, hence, using merge of tuples with the # + operator to add a new imaginary day in the tuple ‘weekdays’
weekdays += ‘Pythonday’,
#Printing the elements of tuple weekdays
print(weekdays)
Output [3]: (‘Sunday’, ‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’, ‘Pythonday’)
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(weekdays)))
Output [4]: 0x1691cc8ad68
This above example shows that we were able to use the same variable name that is referencing an object which is a type of tuple with seven elements in it. However, the ID or the memory location of the old & new tuple is not the same. We were not able to change the internal state of the object ‘weekdays’. The Python program manager created a new object in the memory address and the variable name ‘weekdays’ started referencing the new object with eight elements in it. Hence, we can say that the object which is a type of tuple with reference variable name ‘weekdays’ is an IMMUTABLE OBJECT.
Also Read: Understanding the Exploratory Data Analysis (EDA) in Python
Where can you use mutable and immutable objects:
Mutable objects can be used where you want to allow for any updates. For example, you have a list of employee names in your organizations, and that needs to be updated every time a new member is hired. You can create a mutable list, and it can be updated easily.
Immutability offers a lot of useful applications to different sensitive tasks we do in a network centred environment where we allow for parallel processing. By creating immutable objects, you seal the values and ensure that no threads can invoke overwrite/update to your data. This is also useful in situations where you would like to write a piece of code that cannot be modified. For example, a debug code that attempts to find the value of an immutable object.
Watch outs: Non transitive nature of Immutability:
OK! Now we do understand what mutable & immutable objects in Python are. Let’s go ahead and discuss the combination of these two and explore the possibilities. Let’s discuss, as to how will it behave if you have an immutable object which contains the mutable object(s)? Or vice versa? Let us again use a code to understand this behaviour–
#creating a tuple (immutable object) which contains 2 lists(mutable) as it’s elements
#The elements (lists) contains the name, age & gender
person = (['Ayaan', 5, 'Male'], ['Aaradhya', 8, 'Female'])
#printing the tuple
print(person)
Output [1]: (['Ayaan', 5, 'Male'], ['Aaradhya', 8, 'Female'])
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(person)))
Output [2]: 0x1691ef47f88
#Changing the age for the 1st element. Selecting 1st element of tuple by using indexing [0] then 2nd element of the list by using indexing [1] and assigning a new value for age as 4
person[0][1] = 4
#printing the updated tuple
print(person)
Output [3]: (['Ayaan', 4, 'Male'], ['Aaradhya', 8, 'Female'])
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(person)))
Output [4]: 0x1691ef47f88
In the above code, you can see that the object ‘person’ is immutable since it is a type of tuple. However, it has two lists as it’s elements, and we can change the state of lists (lists being mutable). So, here we did not change the object reference inside the Tuple, but the referenced object was mutated.
Also Read: Real-Time Object Detection Using TensorFlow
Same way, let’s explore how it will behave if you have a mutable object which contains an immutable object? Let us again use a code to understand the behaviour–
#creating a list (mutable object) which contains tuples(immutable) as it’s elements
list1 = [(1, 2, 3), (4, 5, 6)]
#printing the list
print(list1)
Output [1]: [(1, 2, 3), (4, 5, 6)]
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(list1)))
Output [2]: 0x1691d5b13c8
#changing object reference at index 0
list1[0] = (7, 8, 9)
#printing the list
Output [3]: [(7, 8, 9), (4, 5, 6)]
#printing the location of the object created in the memory address in hexadecimal format
print(hex(id(list1)))
Output [4]: 0x1691d5b13c8
As an individual, it completely depends upon you and your requirements as to what kind of data structure you would like to create with a combination of mutable & immutable objects. I hope that this information will help you while deciding the type of object you would like to select going forward.
Before I end our discussion on IMMUTABILITY, allow me to use the word ‘CAVITE’ when we discuss the String and Integers. There is an exception, and you may see some surprising results while checking the truthiness for immutability. For instance:
#creating an object of integer type with value 10 and reference variable name ‘x’
x = 10
#printing the value of ‘x’
print(x)
Output [1]: 10
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(x)))
Output [2]: 0x538fb560
#creating an object of integer type with value 10 and reference variable name ‘y’
y = 10
#printing the value of ‘y’
print(y)
Output [3]: 10
#Printing the location of the object created in the memory address in hexadecimal format
print(hex(id(y)))
Output [4]: 0x538fb560
As per our discussion and understanding, so far, the memory address for x & y should have been different, since, 10 is an instance of Integer class which is immutable. However, as shown in the above code, it has the same memory address. This is not something that we expected. It seems that what we have understood and discussed, has an exception as well.
Quick check – Python Data Structures
Tuples are immutable and hence cannot have any changes in them once they are created in Python. This is because they support the same sequence operations as strings. We all know that strings are immutable. The index operator will select an element from a tuple just like in a string. Hence, they are immutable.
Like all, there are exceptions in the immutability in python too. Not all immutable objects are really mutable. This will lead to a lot of doubts in your mind. Let us just take an example to understand this.
Consider a tuple ‘tup’.
Now, if we consider tuple tup = (‘GreatLearning’,[4,3,1,2]) ;
We see that the tuple has elements of different data types. The first element here is a string which as we all know is immutable in nature. The second element is a list which we all know is mutable. Now, we all know that the tuple itself is an immutable data type. It cannot change its contents. But, the list inside it can change its contents. So, the value of the Immutable objects cannot be changed but its constituent objects can. change its value.
Mutable Object | Immutable Object |
State of the object can be modified after it is created. | State of the object can’t be modified once it is created. |
They are not thread safe. | They are thread safe |
Mutable classes are not final. | It is important to make the class final before creating an immutable object. |
list, dictionary, set, user-defined classes.
int, float, decimal, bool, string, tuple, range.
Lists in Python are mutable data types as the elements of the list can be modified, individual elements can be replaced, and the order of elements can be changed even after the list has been created.
(Examples related to lists have been discussed earlier in this blog.)
Tuple and list data structures are very similar, but one big difference between the data types is that lists are mutable, whereas tuples are immutable. The reason for the tuple’s immutability is that once the elements are added to the tuple and the tuple has been created; it remains unchanged.
A programmer would always prefer building a code that can be reused instead of making the whole data object again. Still, even though tuples are immutable, like lists, they can contain any Python object, including mutable objects.
A set is an iterable unordered collection of data type which can be used to perform mathematical operations (like union, intersection, difference etc.). Every element in a set is unique and immutable, i.e. no duplicate values should be there, and the values can’t be changed. However, we can add or remove items from the set as the set itself is mutable.
Strings are not mutable in Python. Strings are a immutable data types which means that its value cannot be updated.
Join Great Learning Academy’s free online courses and upgrade your skills today.
Original article source at: https://www.mygreatlearning.com
1672928580
Bash has no built-in function to take the user’s input from the terminal. The read command of Bash is used to take the user’s input from the terminal. This command has different options to take an input from the user in different ways. Multiple inputs can be taken using the single read command. Different ways of using this command in the Bash script are described in this tutorial.
read [options] [var1, var2, var3…]
The read command can be used without any argument or option. Many types of options can be used with this command to take the input of the particular data type. It can take more input from the user by defining the multiple variables with this command.
Some options of the read command require an additional parameter to use. The most commonly used options of the read command are mentioned in the following:
Option | Purpose |
---|---|
-d <delimiter> | It is used to take the input until the delimiter value is provided. |
-n <number> | It is used to take the input of a particular number of characters from the terminal and stop taking the input earlier based on the delimiter. |
-N <number> | It is used to take the input of the particular number of characters from the terminal, ignoring the delimiter. |
-p <prompt> | It is used to print the output of the prompt message before taking the input. |
-s | It is used to take the input without an echo. This option is mainly used to take the input for the password input. |
-a | It is used to take the input for the indexed array. |
-t <time> | It is used to set a time limit for taking the input. |
-u <file descriptor> | It is used to take the input from the file. |
-r | It is used to disable the backslashes. |
The uses of read command with different options are shown in this part of this tutorial.
Example 1: Using Read Command without Any Option and variable
Create a Bash file with the following script that takes the input from the terminal using the read command without any option and variable. If no variable is used with the read command, the input value is stored in the $REPLY variable. The value of this variable is printed later after taking the input.
#!/bin/bash
#Print the prompt message
echo "Enter your favorite color: "
#Take the input
read
#Print the input value
echo "Your favorite color is $REPLY"
Output:
The following output appears if the “Blue” value is taken as an input:
Example 2: Using Read Command with a Variable
Create a Bash file with the following script that takes the input from the terminal using the read command with a variable. The method of taking the single or multiple variables using a read command is shown in this example. The values of all variables are printed later.
#!/bin/bash
#Print the prompt message
echo "Enter the product name: "
#Take the input with a single variable
read item
#Print the prompt message
echo "Enter the color variations of the product: "
#Take three input values in three variables
read color1 color2 color3
#Print the input value
echo "The product name is $item."
#Print the input values
echo "Available colors are $color1, $color2, and $color3."
Output:
The following output appears after taking a single input first and three inputs later:
Example 3: Using Read Command with -p Option
Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -p option. The input value is printed later.
#!/bin/bash
#Take the input with the prompt message
read -p "Enter the book name: " book
#Print the input value
echo "Book name: $book"
Output:
The following output appears after taking the input:
Example 4: Using Read Command with -s Option
Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -s option. The input value of the password will not be displayed for the -s option. The input values are checked later for authentication. A success or failure message is also printed.
#!/bin/bash
#Take the input with the prompt message
read -p "Enter your email: " email
#Take the secret input with the prompt message
read -sp "Enter your password: " password
#Add newline
echo ""
#Check the email and password for authentication
if [[ $email == "admin@example.com" && $password == "secret" ]]
then
#Print the success message
echo "Authenticated."
else
#Print the failure message
echo "Not authenticated."
fi
Output:
The following output appears after taking the valid and invalid input values:
Example 5: Using Read Command with -a Option
Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -a option. The array values are printed later after taking the input values from the terminal.
#!/bin/bash
echo "Enter the country names: "
#Take multiple inputs using an array
read -a countries
echo "Country names are:"
#Read the array values
for country in ${countries[@]}
do
echo $country
done
Output:
The following output appears after taking the array values:
Example 6: Using Read Command with -n Option
Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -n option.
#!/bin/bash
#Print the prompt message
echo "Enter the product code: "
#Take the input of five characters
read -n 5 code
#Add newline
echo ""
#Print the input value
echo "The product code is $code"
Output:
The following output appears if the “78342” value is taken as input:
Example 7: Using Read Command with -t Option
Create a Bash file with the following script that takes the input from the terminal using the read command with a variable and the -t option.
#!/bin/bash
#Print the prompt message
echo -n "Write the result of 10-6: "
#Take the input of five characters
read -t 3 answer
#Check the input value
if [[ $answer == "4" ]]
then
echo "Correct answer."
else
echo "Incorrect answer."
fi
Output:
The following output appears after taking the correct and incorrect input values:
The uses of some useful options of the read command are explained in this tutorial using multiple examples to know the basic uses of the read command.
Original article source at: https://linuxhint.com/
1646796864
Trong bài viết này, bạn sẽ học cách sử dụng phương pháp danh sách của Python sort()
.
Bạn cũng sẽ tìm hiểu một cách khác để thực hiện sắp xếp trong Python bằng cách sử dụng sorted()
hàm để bạn có thể thấy nó khác với nó như thế nào sort()
.
Cuối cùng, bạn sẽ biết những điều cơ bản về sắp xếp danh sách bằng Python và biết cách tùy chỉnh việc sắp xếp để phù hợp với nhu cầu của bạn.
sort()
- Tổng quan về cú phápPhương pháp sort()
này là một trong những cách bạn có thể sắp xếp danh sách trong Python.
Khi sử dụng sort()
, bạn sắp xếp một danh sách tại chỗ . Điều này có nghĩa là danh sách ban đầu được sửa đổi trực tiếp. Cụ thể, thứ tự ban đầu của các phần tử bị thay đổi.
Cú pháp chung cho phương thức sort()
này trông giống như sau:
list_name.sort(reverse=..., key=... )
Hãy chia nhỏ nó:
list_name
là tên của danh sách bạn đang làm việc.sort()
là một trong những phương pháp danh sách của Python để sắp xếp và thay đổi danh sách. Nó sắp xếp các phần tử danh sách theo thứ tự tăng dần hoặc giảm dần .sort()
chấp nhận hai tham số tùy chọn .reverse
là tham số tùy chọn đầu tiên. Nó chỉ định liệu danh sách sẽ được sắp xếp theo thứ tự tăng dần hay giảm dần. Nó nhận một giá trị Boolean, nghĩa là giá trị đó là True hoặc False. Giá trị mặc định là False , nghĩa là danh sách được sắp xếp theo thứ tự tăng dần. Đặt nó thành True sẽ sắp xếp danh sách ngược lại, theo thứ tự giảm dần.key
là tham số tùy chọn thứ hai. Nó có một hàm hoặc phương pháp được sử dụng để chỉ định bất kỳ tiêu chí sắp xếp chi tiết nào mà bạn có thể có.Phương sort()
thức trả về None
, có nghĩa là không có giá trị trả về vì nó chỉ sửa đổi danh sách ban đầu. Nó không trả về một danh sách mới.
sort()
Như đã đề cập trước đó, theo mặc định, sort()
sắp xếp các mục trong danh sách theo thứ tự tăng dần.
Thứ tự tăng dần (hoặc tăng dần) có nghĩa là các mặt hàng được sắp xếp từ giá trị thấp nhất đến cao nhất.
Giá trị thấp nhất ở bên trái và giá trị cao nhất ở bên phải.
Cú pháp chung để thực hiện việc này sẽ giống như sau:
list_name.sort()
Hãy xem ví dụ sau đây cho thấy cách sắp xếp danh sách các số nguyên:
# a list of numbers
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]
#sort list in-place in ascending order
my_numbers.sort()
#print modified list
print(my_numbers)
#output
#[3, 7, 8, 10, 11, 22, 33, 54, 100]
Trong ví dụ trên, các số được sắp xếp từ nhỏ nhất đến lớn nhất.
Bạn cũng có thể đạt được điều tương tự khi làm việc với danh sách các chuỗi:
# a list of strings
programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]
#sort list in-place in alphabetical order
programming_languages.sort()
#print modified list
print(programming_languages)
#output
#['C++', 'Go', 'Java', 'Python', 'Rust', 'Swift']
Trong trường hợp này, mỗi chuỗi có trong danh sách được sắp xếp theo thứ tự không tuân theo.
Như bạn đã thấy trong cả hai ví dụ, danh sách ban đầu đã được thay đổi trực tiếp.
sort()
Thứ tự giảm dần (hoặc giảm dần) ngược lại với thứ tự tăng dần - các phần tử được sắp xếp từ giá trị cao nhất đến thấp nhất.
Để sắp xếp các mục trong danh sách theo thứ tự giảm dần, bạn cần sử dụng reverse
tham số tùy chọn với phương thức sort()
và đặt giá trị của nó thành True
.
Cú pháp chung để thực hiện việc này sẽ giống như sau:
list_name.sort(reverse=True)
Hãy sử dụng lại cùng một ví dụ từ phần trước, nhưng lần này làm cho nó để các số được sắp xếp theo thứ tự ngược lại:
# a list of numbers
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]
#sort list in-place in descending order
my_numbers.sort(reverse=True)
#print modified list
print(my_numbers)
#output
#[100, 54, 33, 22, 11, 10, 8, 7, 3]
Bây giờ tất cả các số được sắp xếp ngược lại, với giá trị lớn nhất ở bên tay trái và giá trị nhỏ nhất ở bên phải.
Bạn cũng có thể đạt được điều tương tự khi làm việc với danh sách các chuỗi.
# a list of strings
programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]
#sort list in-place in reverse alphabetical order
programming_languages.sort(reverse=True)
#print modified list
print(programming_languages)
#output
#['Swift', 'Rust', 'Python', 'Java', 'Go', 'C++']
Các mục danh sách hiện được sắp xếp theo thứ tự bảng chữ cái ngược lại.
key
tham số với phương thức sort()
Bạn có thể sử dụng key
tham số để thực hiện các thao tác sắp xếp tùy chỉnh hơn.
Giá trị được gán cho key
tham số cần phải là thứ có thể gọi được.
Callable là thứ có thể được gọi, có nghĩa là nó có thể được gọi và tham chiếu.
Một số ví dụ về các đối tượng có thể gọi là các phương thức và hàm.
Phương thức hoặc hàm được gán cho key
này sẽ được áp dụng cho tất cả các phần tử trong danh sách trước khi bất kỳ quá trình sắp xếp nào xảy ra và sẽ chỉ định logic cho tiêu chí sắp xếp.
Giả sử bạn muốn sắp xếp danh sách các chuỗi dựa trên độ dài của chúng.
Đối với điều đó, bạn chỉ định len()
hàm tích hợp cho key
tham số.
Hàm len()
sẽ đếm độ dài của từng phần tử được lưu trong danh sách bằng cách đếm các ký tự có trong phần tử đó.
programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]
programming_languages.sort(key=len)
print(programming_languages)
#output
#['Go', 'C++', 'Java', 'Rust', 'Swift', 'Python']
Trong ví dụ trên, các chuỗi được sắp xếp theo thứ tự tăng dần mặc định, nhưng lần này việc sắp xếp xảy ra dựa trên độ dài của chúng.
Chuỗi ngắn nhất ở bên trái và dài nhất ở bên phải.
Các key
và reverse
tham số cũng có thể được kết hợp.
Ví dụ: bạn có thể sắp xếp các mục trong danh sách dựa trên độ dài của chúng nhưng theo thứ tự giảm dần.
programming_languages = ["Python", "Swift","Java", "C++", "Go", "Rust"]
programming_languages.sort(key=len, reverse=True)
print(programming_languages)
#output
#['Python', 'Swift', 'Java', 'Rust', 'C++', 'Go']
Trong ví dụ trên, các chuỗi đi từ dài nhất đến ngắn nhất.
Một điều cần lưu ý nữa là bạn có thể tạo một chức năng sắp xếp tùy chỉnh của riêng mình, để tạo các tiêu chí sắp xếp rõ ràng hơn.
Ví dụ: bạn có thể tạo một hàm cụ thể và sau đó sắp xếp danh sách theo giá trị trả về của hàm đó.
Giả sử bạn có một danh sách các từ điển với các ngôn ngữ lập trình và năm mà mỗi ngôn ngữ lập trình được tạo ra.
programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]
Bạn có thể xác định một hàm tùy chỉnh nhận giá trị của một khóa cụ thể từ từ điển.
💡 Hãy nhớ rằng khóa từ điển và key
tham số sort()
chấp nhận là hai thứ khác nhau!
Cụ thể, hàm sẽ lấy và trả về giá trị của year
khóa trong danh sách từ điển, chỉ định năm mà mọi ngôn ngữ trong từ điển được tạo.
Giá trị trả về sau đó sẽ được áp dụng làm tiêu chí sắp xếp cho danh sách.
programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]
def get_year(element):
return element['year']
Sau đó, bạn có thể sắp xếp theo giá trị trả về của hàm bạn đã tạo trước đó bằng cách gán nó cho key
tham số và sắp xếp theo thứ tự thời gian tăng dần mặc định:
programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]
def get_year(element):
return element['year']
programming_languages.sort(key=get_year)
print(programming_languages)
Đầu ra:
[{'language': 'C++', 'year': 1985}, {'language': 'Python', 'year': 1991}, {'language': 'Java', 'year': 1995}, {'language': 'Go', 'year': 2007}, {'language': 'Rust', 'year': 2010}, {'language': 'Swift', 'year': 2014}]
Nếu bạn muốn sắp xếp từ ngôn ngữ được tạo gần đây nhất đến ngôn ngữ cũ nhất hoặc theo thứ tự giảm dần, thì bạn sử dụng reverse=True
tham số:
programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]
def get_year(element):
return element['year']
programming_languages.sort(key=get_year, reverse=True)
print(programming_languages)
Đầu ra:
[{'language': 'Swift', 'year': 2014}, {'language': 'Rust', 'year': 2010}, {'language': 'Go', 'year': 2007}, {'language': 'Java', 'year': 1995}, {'language': 'Python', 'year': 1991}, {'language': 'C++', 'year': 1985}]
Để đạt được kết quả chính xác, bạn có thể tạo một hàm lambda.
Thay vì sử dụng hàm tùy chỉnh thông thường mà bạn đã xác định bằng def
từ khóa, bạn có thể:
def
hàm. Các hàm lambda còn được gọi là các hàm ẩn danh .programming_languages = [{'language':'Python','year':1991},
{'language':'Swift','year':2014},
{'language':'Java', 'year':1995},
{'language':'C++','year':1985},
{'language':'Go','year':2007},
{'language':'Rust','year':2010},
]
programming_languages.sort(key=lambda element: element['year'])
print(programming_languages)
Hàm lambda được chỉ định với dòng key=lambda element: element['year']
sắp xếp các ngôn ngữ lập trình này từ cũ nhất đến mới nhất.
sort()
và sorted()
Phương sort()
thức hoạt động theo cách tương tự như sorted()
hàm.
Cú pháp chung của sorted()
hàm trông như sau:
sorted(list_name,reverse=...,key=...)
Hãy chia nhỏ nó:
sorted()
là một hàm tích hợp chấp nhận một có thể lặp lại. Sau đó, nó sắp xếp nó theo thứ tự tăng dần hoặc giảm dần.sorted()
chấp nhận ba tham số. Một tham số là bắt buộc và hai tham số còn lại là tùy chọn.list_name
là tham số bắt buộc . Trong trường hợp này, tham số là danh sách, nhưng sorted()
chấp nhận bất kỳ đối tượng có thể lặp lại nào khác.sorted()
cũng chấp nhận các tham số tùy chọn reverse
và key
, đó là các tham số tùy chọn tương tự mà phương thức sort()
chấp nhận.Sự khác biệt chính giữa sort()
và sorted()
là sorted()
hàm nhận một danh sách và trả về một bản sao được sắp xếp mới của nó.
Bản sao mới chứa các phần tử của danh sách ban đầu theo thứ tự được sắp xếp.
Các phần tử trong danh sách ban đầu không bị ảnh hưởng và không thay đổi.
Vì vậy, để tóm tắt sự khác biệt:
sort()
thức không có giá trị trả về và trực tiếp sửa đổi danh sách ban đầu, thay đổi thứ tự của các phần tử chứa trong nó.sorted()
hàm có giá trị trả về, là một bản sao đã được sắp xếp của danh sách ban đầu. Bản sao đó chứa các mục danh sách của danh sách ban đầu theo thứ tự được sắp xếp. Cuối cùng, danh sách ban đầu vẫn còn nguyên vẹn.Hãy xem ví dụ sau để xem nó hoạt động như thế nào:
#original list of numbers
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]
#sort original list in default ascending order
my_numbers_sorted = sorted(my_numbers)
#print original list
print(my_numbers)
#print the copy of the original list that was created
print(my_numbers_sorted)
#output
#[10, 8, 3, 22, 33, 7, 11, 100, 54]
#[3, 7, 8, 10, 11, 22, 33, 54, 100]
Vì không có đối số bổ sung nào được cung cấp sorted()
, nó đã sắp xếp bản sao của danh sách ban đầu theo thứ tự tăng dần mặc định, từ giá trị nhỏ nhất đến giá trị lớn nhất.
Và khi in danh sách ban đầu, bạn thấy rằng nó vẫn được giữ nguyên và các mục có thứ tự ban đầu.
Như bạn đã thấy trong ví dụ trên, bản sao của danh sách đã được gán cho một biến mới my_numbers_sorted
,.
Một cái gì đó như vậy không thể được thực hiện với sort()
.
Hãy xem ví dụ sau để xem điều gì sẽ xảy ra nếu điều đó được thực hiện với phương thức sort()
.
my_numbers = [10, 8, 3, 22, 33, 7, 11, 100, 54]
my_numbers_sorted = my_numbers.sort()
print(my_numbers)
print(my_numbers_sorted)
#output
#[3, 7, 8, 10, 11, 22, 33, 54, 100]
#None
Bạn thấy rằng giá trị trả về của sort()
là None
.
Cuối cùng, một điều khác cần lưu ý là các reverse
và key
tham số mà sorted()
hàm chấp nhận hoạt động giống hệt như cách chúng thực hiện với phương thức sort()
bạn đã thấy trong các phần trước.
sort()
vàsorted()
Dưới đây là một số điều bạn có thể muốn xem xét khi quyết định có nên sử dụng sort()
vs. sorted()
Trước tiên, hãy xem xét loại dữ liệu bạn đang làm việc:
sort()
phương pháp này vì sort()
chỉ được gọi trong danh sách.sorted()
. Hàm sorted()
chấp nhận và sắp xếp mọi thứ có thể lặp lại (như từ điển, bộ giá trị và bộ) chứ không chỉ danh sách.Tiếp theo, một điều khác cần xem xét là liệu bạn có giữ được thứ tự ban đầu của danh sách mà bạn đang làm việc hay không:
sort()
, danh sách ban đầu sẽ bị thay đổi và mất thứ tự ban đầu. Bạn sẽ không thể truy xuất vị trí ban đầu của các phần tử danh sách. Sử dụng sort()
khi bạn chắc chắn muốn thay đổi danh sách đang làm việc và chắc chắn rằng bạn không muốn giữ lại thứ tự đã có.sorted()
nó hữu ích khi bạn muốn tạo một danh sách mới nhưng bạn vẫn muốn giữ lại danh sách bạn đang làm việc. Hàm sorted()
sẽ tạo một danh sách được sắp xếp mới với các phần tử danh sách được sắp xếp theo thứ tự mong muốn.Cuối cùng, một điều khác mà bạn có thể muốn xem xét khi làm việc với các tập dữ liệu lớn hơn, đó là hiệu quả về thời gian và bộ nhớ:
sort()
pháp này chiếm dụng và tiêu tốn ít bộ nhớ hơn vì nó chỉ sắp xếp danh sách tại chỗ và không tạo ra danh sách mới không cần thiết mà bạn không cần. Vì lý do tương tự, nó cũng nhanh hơn một chút vì nó không tạo ra một bản sao. Điều này có thể hữu ích khi bạn đang làm việc với danh sách lớn hơn chứa nhiều phần tử hơn.Và bạn có nó rồi đấy! Bây giờ bạn đã biết cách sắp xếp một danh sách trong Python bằng sort()
phương pháp này.
Bạn cũng đã xem xét sự khác biệt chính giữa sắp xếp danh sách bằng cách sử dụng sort()
và sorted()
.
Tôi hy vọng bạn thấy bài viết này hữu ích.
Để tìm hiểu thêm về ngôn ngữ lập trình Python, hãy xem Chứng chỉ Máy tính Khoa học với Python của freeCodeCamp .
Bạn sẽ bắt đầu từ những điều cơ bản và học theo cách tương tác và thân thiện với người mới bắt đầu. Bạn cũng sẽ xây dựng năm dự án vào cuối để áp dụng vào thực tế và giúp củng cố những gì bạn đã học được.
Nguồn: https://www.freecodecamp.org/news/python-sort-how-to-sort-a-list-in-python/
1635844372
Aprenda a usar la biblioteca de transformadores Huggingface para generar respuestas conversacionales con el modelo DialoGPT previamente entrenado en Python.
Los chatbots han ganado mucha popularidad en los últimos años y, a medida que crece el interés en el uso de chatbots para empresas, los investigadores también hicieron un gran trabajo en el avance de los chatbots de IA conversacionales.
En este tutorial, usaremos la biblioteca de transformadores Huggingface para emplear el modelo DialoGPT previamente entrenado para la generación de respuestas conversacionales.
DialoGPT es un modelo de generación de respuesta conversacional neuronal sintonizable a gran escala que se entrenó en 147 millones de conversaciones extraídas de Reddit, y lo bueno es que puede ajustarlo con su conjunto de datos para lograr un mejor rendimiento que el entrenamiento desde cero.
Para comenzar, instalemos transformadores :
$ pip3 install transformers
Abra un nuevo archivo o cuaderno de Python y haga lo siguiente:
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# model_name = "microsoft/DialoGPT-large"
model_name = "microsoft/DialoGPT-medium"
# model_name = "microsoft/DialoGPT-small"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
Hay tres versiones de DialoGPT; pequeño, mediano y grande. Por supuesto, cuanto más grande, mejor, pero si ejecuta esto en su máquina, creo que el tamaño pequeño o mediano se adapta a su memoria sin problemas. También puede utilizar Google Colab para probar el más grande.
En esta sección, usaremos el algoritmo de búsqueda codiciosa para generar respuestas. Es decir, seleccionamos la respuesta del chatbot que tiene la mayor probabilidad de ser seleccionada en cada paso de tiempo.
Hagamos un código para chatear con nuestra IA usando una búsqueda codiciosa:
# chatting 5 times with greedy search
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
pad_token_id=tokenizer.eos_token_id,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Expliquemos el núcleo de este código:
input_ids
usar el tokenizador DialoGPT, también agregamos el final del token de cadena y lo devolvemos como un tensor de Pytorch.input_ids
nuestro modelo durante una generación. De lo contrario, agregamos el historial de chat usando la concatenación con la ayuda del torch.cat()
método.model.generate()
método para generar la respuesta del chatbot.tokenizer.decode()
y configuramos skip_special_tokens
para True
asegurarnos de que no veamos ningún token especial molesto como <|endoftext|>
. Además, dado que el modelo devuelve la secuencia completa, omitimos el historial de chat anterior e imprimimos solo la respuesta del chatbot recién generada.A continuación se muestra una discusión de muestra con el bot:
>> You:How can you be rich so quickly?
DialoGPT: I'm not rich, I'm just a rich man.
>> You:Ok, you don't make sense, how old are you ?
DialoGPT: I'm not a rich man, I'm just a rich man.
>> You:How can you be happy ?
DialoGPT: I'm not happy, I'm just a rich man.
>> You:But they say money buys happiness!
DialoGPT: Money buys happiness, but not happiness itself.
>> You:You don't make sense again!
DialoGPT: I'm not happy, I'm just a rich man.
Verá que el modelo repite muchas respuestas, ya que estas son la probabilidad más alta y lo elige cada vez.
De forma predeterminada, model.generate()
utiliza un algoritmo de búsqueda codicioso cuando no se establecen otros parámetros; en las siguientes secciones, agregaremos algunos argumentos a este método para ver si podemos mejorar la generación.
La búsqueda por haz nos permite reducir el riesgo de perder secuencias de alta probabilidad al mantener las num_beams
hipótesis más probables en cada paso de tiempo y luego tomar las secuencias que tienen la probabilidad general más alta, el siguiente código generará respuestas de chatbot con búsqueda de haz:
# chatting 5 times with beam search
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
num_beams=3,
early_stopping=True,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Cuando se ajusta num_beams
a 3
de model.generate()
método, a continuación, vamos a seleccionar 3 palabras en cada paso de tiempo y desarrollarlas para encontrar la más alta probabilidad global de la secuencia, el establecimiento num_beams
de 1 es la misma que la búsqueda codiciosa.
A continuación se muestra una discusión de muestra con el chatbot usando la búsqueda de haz:
>> You:How can I be rich?
DialoGPT: You can't.
>> You:Why not?
DialoGPT: Because you can't.
>> You:Then how am I supposed to live well?
DialoGPT: You can't.
>> You:So basically, you want me to be a poor guy?
DialoGPT: No, I want you to be a rich guy.
>> You:Ok how to be rich, then?
DialoGPT: I don't know.
En las secciones anteriores, usamos la búsqueda de rayos y codiciosos para generar la secuencia de probabilidad más alta. Eso es genial para tareas como la traducción automática o el resumen de texto donde el resultado es predecible. Sin embargo, no es la mejor opción para una generación abierta como en los chatbots.
Para una mejor generación, necesitamos introducir algo de aleatoriedad donde muestreamos de una amplia gama de secuencias candidatas basadas en probabilidades:
# chatting 5 times with sampling
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_k=0,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Esta vez, establece do_sample
que True
para el muestreo, y nos pusimos top_k
a 0
lo que indica que estamos seleccionando todas las probabilidades posibles, vamos a discutir más adelante top_k
parámetro.
Aquí hay un chat con estos parámetros:
>> You:Hello, how can I be rich?
DialoGPT: You can't
>> You:Really? then how others get rich?
DialoGPT: They work as money artists
>> You:How to be a money artist?
DialoGPT: I don't know, I don't have enough knowledge on artists
>> You:Alright, thank you!
DialoGPT: No problem, if you need tips pm me.
>> You:Great, you're my savior!
DialoGPT: Thank you for helping a stranger out like me!
Claramente hay algunas mejoras. Sin embargo, el muestreo en una amplia lista de secuencias con bajas probabilidades puede conducir a una generación aleatoria (como se ve en la última oración).
Para mejorarlo aún más, podemos:
temperature
Disminuir el muestreo , eso nos ayuda a disminuir la probabilidad de elegir palabras de baja probabilidad y aumentar la probabilidad de elegir palabras de alta probabilidad.# chatting 5 times with Top K sampling & tweaking temperature
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_k=100,
temperature=0.75,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Ahora, configuramos top_k
para 100
muestrear las 100
palabras principales ordenadas de forma descendente por probabilidad. También establecemos temperature
en 0.75
(el valor predeterminado es 1.0
) para brindar una mayor probabilidad de elegir palabras de alta probabilidad, establecer la temperatura en 0.0
es lo mismo que la búsqueda codiciosa, establecerla en infinito es lo mismo que completamente aleatorio.
Aquí hay una discusión con estos parámetros:
>> You:How can I get rich?
DialoGPT: I'd also like to know this.
>> You:So you don't know it?
DialoGPT: I know it, but it doesn't matter.
>> You:Really? money matters, man!
DialoGPT: Well, money is money and I gotta get my money.
>> You:Yeah how to get them?
DialoGPT: Well, that's a question. I'd like to know more, just for curiosity's sake, to know what other people have said about how I should get rich.
>> You:Some robots like you told me you have to buy gold, silver or stocks.
DialoGPT: I think my wallet is empty.
Como se puede ver, es mucho mejor ahora, no dude en modificar temperature
y top_k
parámetros y ver si puede mejorarlo.
El muestreo de núcleo o muestreo de Top-p elige entre las palabras más pequeñas posibles cuya probabilidad acumulada excede el parámetro p
que establecimos.
A continuación se muestra un ejemplo con el muestreo de Top-p:
# chatting 5 times with nucleus sampling & tweaking temperature
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_p=0.95,
top_k=0,
temperature=0.75,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Configuramos top_k
para 0
deshabilitar el muestreo de Top-k, pero puede usar ambos métodos, lo que tiende a funcionar mejor. Aquí hay un chat:
>> You:How can I be rich fast?
DialoGPT: Inflation and free money
>> You:lol, but that takes time, I need fast money.
DialoGPT: Your post makes no sense. You just need a lot of money to be rich fast
>> You:Ok how to get a lot of money?
DialoGPT: Buy gold and then trade it for money.
>> You:Hmm, I got your point, thanks.
DialoGPT: No problem. You have to have money to buy gold, but its only good for trading it.
>> You:Yeah, I understand, thank you so much.
DialoGPT: Ok, let me know if you need help
Ahora el chatbot claramente tiene sentido en muchos casos.
Ahora agreguemos algo de código para generar más de una respuesta de chatbot, y luego elegimos qué respuesta incluir en la siguiente entrada:
# chatting 5 times with nucleus & top-k sampling & tweaking temperature & multiple
# sentences
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids_list = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_p=0.95,
top_k=50,
temperature=0.75,
num_return_sequences=5,
pad_token_id=tokenizer.eos_token_id
)
#print the outputs
for i in range(len(chat_history_ids_list)):
output = tokenizer.decode(chat_history_ids_list[i][bot_input_ids.shape[-1]:], skip_special_tokens=True)
print(f"DialoGPT {i}: {output}")
choice_index = int(input("Choose the response you want for the next input: "))
chat_history_ids = torch.unsqueeze(chat_history_ids_list[choice_index], dim=0)
He configurado num_return_sequences
para 5
devolver 5 oraciones a la vez, tenemos que elegir la que se incluirá en la siguiente secuencia. Así es como fue:
>> You:Hello, friend.
DialoGPT 0: Hey there!
DialoGPT 1: I am your friend, and I am also your friend.
DialoGPT 2: Hello. :
DialoGPT 3: Hiya! How are you?
DialoGPT 4: Hello. I like your username.
Choose the response you want for the next input: 3
>> You:Fine, thanks, what about you?
DialoGPT 0: Good. Not much to do.
DialoGPT 1: Not much, you?
DialoGPT 2: Fine, thanks.
DialoGPT 3: I'm okay, thank you for asking.
DialoGPT 4: I'm fine too.
Choose the response you want for the next input: 2
>> You:Can you tell me how can I get rich quickly?
DialoGPT 0: Yes, I can!
DialoGPT 1: Yes, just look up how to get rich on Google.
DialoGPT 2: Just keep doing your thing. You'll get rich.
DialoGPT 3: No, I can't.
DialoGPT 4: no, i have no money
Choose the response you want for the next input: 1
>> You:Yeah, but I thought you have an answer...
DialoGPT 0: I'm getting married in the morning.
DialoGPT 1: How do you get rich?
DialoGPT 2: I think there are many good answers, but I could send you one, if you want.
DialoGPT 3: I will, thanks!
DialoGPT 4: I thought you have an answer.
Choose the response you want for the next input: 2
>> You:Yes, please send me.
DialoGPT 0: You can send me link.
DialoGPT 1: I am very interested
DialoGPT 2: I sent you a PM
DialoGPT 3: I'll send you a PM
DialoGPT 4: I am always interested in new ideas.
Choose the response you want for the next input: 2
Y ahí lo tienes, espero que este tutorial te haya ayudado a generar texto en DialoGPT y modelos similares. Para obtener más información sobre cómo generar texto, le recomiendo que lea la guía Cómo generar texto con Transformers .
Te dejo ajustando los parámetros para ver si puedes hacer que el bot funcione mejor.
Además, puede combinar esto con tutoriales de texto a voz y de voz a texto para crear un asistente virtual como Alexa , Siri , Cortana , etc.
#python #chatbot #ai
1635843812
Tìm hiểu cách sử dụng thư viện máy biến áp Huggingface để tạo phản hồi hội thoại bằng mô hình DialoGPT được đào tạo trước bằng Python.
Chatbots đã trở nên phổ biến trong những năm gần đây và khi mối quan tâm ngày càng tăng trong việc sử dụng chatbots cho kinh doanh, các nhà nghiên cứu cũng đã làm rất tốt trong việc phát triển các chatbot AI đàm thoại.
Trong hướng dẫn này, chúng tôi sẽ sử dụng thư viện máy biến áp Huggingface để sử dụng mô hình DialoGPT đã được đào tạo trước để tạo phản hồi hội thoại.
DialoGPT là một mô hình tạo phản hồi hội thoại thần kinh có thể điều chỉnh quy mô lớn được đào tạo trên 147 triệu cuộc hội thoại được trích xuất từ Reddit và điều tốt là bạn có thể tinh chỉnh nó với bộ dữ liệu của mình để đạt được hiệu suất tốt hơn so với đào tạo từ đầu.
Để bắt đầu, hãy cài đặt máy biến áp :
$ pip3 install transformers
Mở tệp hoặc sổ ghi chép Python mới và thực hiện như sau:
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# model_name = "microsoft/DialoGPT-large"
model_name = "microsoft/DialoGPT-medium"
# model_name = "microsoft/DialoGPT-small"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
Có ba phiên bản của DialoGPT; nhỏ, vừa và lớn. Tất nhiên, càng lớn càng tốt, nhưng nếu bạn chạy điều này trên máy của mình, tôi nghĩ nhỏ hoặc trung bình phù hợp với bộ nhớ của bạn mà không có vấn đề gì. Bạn cũng có thể sử dụng Google Colab để thử cái lớn.
Trong phần này, chúng tôi sẽ sử dụng thuật toán tìm kiếm tham lam để tạo phản hồi. Đó là, chúng tôi chọn phản hồi chatbot có xác suất cao nhất được chọn trên mỗi bước thời gian.
Hãy tạo mã để trò chuyện với AI của chúng tôi bằng cách sử dụng tìm kiếm tham lam:
# chatting 5 times with greedy search
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
pad_token_id=tokenizer.eos_token_id,
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Hãy giải thích cốt lõi của mã này:
input_ids
bằng cách sử dụng trình mã hóa DialoGPT, chúng tôi cũng nối vào cuối chuỗi mã thông báo và trả về nó dưới dạng bộ căng Pytorch.input_ids
cho mô hình của mình trong một thế hệ. Nếu không, chúng tôi nối lịch sử trò chuyện bằng cách nối với sự trợ giúp của torch.cat()
phương thức.model.generate()
phương pháp tạo phản hồi chatbot.tokenizer.decode()
và thiết lập skip_special_tokens
để True
đảm bảo chúng tôi không thấy bất kỳ đặc biệt gây phiền nhiễu mã thông báo như <|endoftext|>
. Ngoài ra, vì mô hình trả về toàn bộ chuỗi, chúng tôi bỏ qua lịch sử trò chuyện trước đó và chỉ in câu trả lời chatbot mới được tạo.Dưới đây là một cuộc thảo luận mẫu với bot:
>> You:How can you be rich so quickly?
DialoGPT: I'm not rich, I'm just a rich man.
>> You:Ok, you don't make sense, how old are you ?
DialoGPT: I'm not a rich man, I'm just a rich man.
>> You:How can you be happy ?
DialoGPT: I'm not happy, I'm just a rich man.
>> You:But they say money buys happiness!
DialoGPT: Money buys happiness, but not happiness itself.
>> You:You don't make sense again!
DialoGPT: I'm not happy, I'm just a rich man.
Bạn thấy mô hình lặp lại rất nhiều phản hồi, vì đây là xác suất cao nhất và nó luôn chọn nó.
Theo mặc định, model.generate()
sử dụng thuật toán tìm kiếm tham lam khi không có tham số nào khác được đặt, trong các phần tiếp theo, chúng tôi sẽ thêm một số đối số vào phương thức này để xem liệu chúng tôi có thể cải thiện việc tạo không.
Tìm kiếm theo chùm cho phép chúng tôi giảm nguy cơ bỏ lỡ các chuỗi có xác suất cao bằng cách giữ lại num_beams
các giả thuyết có khả năng xảy ra nhất ở mỗi bước thời gian và sau đó lấy các chuỗi có xác suất cao nhất tổng thể, đoạn mã dưới đây sẽ tạo ra các phản hồi của chatbot với tìm kiếm theo chùm:
# chatting 5 times with beam search
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
num_beams=3,
early_stopping=True,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Khi đặt num_beams
thành 3
trong model.generate()
phương thức, chúng tôi sẽ chọn 3 từ ở mỗi bước và phát triển chúng để tìm xác suất tổng thể cao nhất của chuỗi, đặt num_beams
thành 1 cũng giống như tìm kiếm tham lam.
Dưới đây là một cuộc thảo luận mẫu với chatbot bằng cách sử dụng tìm kiếm chùm:
>> You:How can I be rich?
DialoGPT: You can't.
>> You:Why not?
DialoGPT: Because you can't.
>> You:Then how am I supposed to live well?
DialoGPT: You can't.
>> You:So basically, you want me to be a poor guy?
DialoGPT: No, I want you to be a rich guy.
>> You:Ok how to be rich, then?
DialoGPT: I don't know.
Trong các phần trước, chúng tôi đã sử dụng tìm kiếm chùm và tham lam để tạo ra chuỗi xác suất cao nhất. Giờ đây, điều đó thật tuyệt vời cho các tác vụ như dịch máy hoặc tóm tắt văn bản trong đó kết quả đầu ra có thể dự đoán được. Tuy nhiên, nó không phải là lựa chọn tốt nhất cho thế hệ kết thúc mở như trong chatbots.
Để có một thế hệ tốt hơn, chúng tôi cần đưa ra một số ngẫu nhiên trong đó chúng tôi lấy mẫu từ một loạt các trình tự ứng viên dựa trên xác suất:
# chatting 5 times with sampling
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_k=0,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Lần này, chúng tôi đặt do_sample
để True
lấy mẫu và chúng tôi đặt top_k
để 0
chỉ ra rằng chúng tôi đang chọn tất cả các xác suất có thể xảy ra, sau đó chúng ta sẽ thảo luận về top_k
tham số.
Đây là một cuộc trò chuyện với các thông số này:
>> You:Hello, how can I be rich?
DialoGPT: You can't
>> You:Really? then how others get rich?
DialoGPT: They work as money artists
>> You:How to be a money artist?
DialoGPT: I don't know, I don't have enough knowledge on artists
>> You:Alright, thank you!
DialoGPT: No problem, if you need tips pm me.
>> You:Great, you're my savior!
DialoGPT: Thank you for helping a stranger out like me!
Rõ ràng là có một số cải tiến. Tuy nhiên, việc lấy mẫu trên một danh sách rộng các chuỗi với xác suất thấp có thể dẫn đến việc tạo ngẫu nhiên (như bạn thấy trong câu cuối cùng).
Để cải thiện nó hơn nữa, chúng tôi có thể:
temperature
, điều đó giúp chúng tôi giảm khả năng chọn các từ có xác suất thấp và tăng khả năng chọn các từ có xác suất cao.# chatting 5 times with Top K sampling & tweaking temperature
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_k=100,
temperature=0.75,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Bây giờ, chúng ta thiết lập top_k
để 100
lấy mẫu từ đỉnh 100
từ được sắp xếp descendingly bởi xác suất. Chúng tôi cũng đặt temperature
thành 0.75
(mặc định là 1.0
) để có cơ hội chọn các từ có xác suất cao hơn, đặt nhiệt độ 0.0
giống như tìm kiếm tham lam, đặt nhiệt độ thành vô cùng giống như hoàn toàn ngẫu nhiên.
Đây là một cuộc thảo luận với các thông số này:
>> You:How can I get rich?
DialoGPT: I'd also like to know this.
>> You:So you don't know it?
DialoGPT: I know it, but it doesn't matter.
>> You:Really? money matters, man!
DialoGPT: Well, money is money and I gotta get my money.
>> You:Yeah how to get them?
DialoGPT: Well, that's a question. I'd like to know more, just for curiosity's sake, to know what other people have said about how I should get rich.
>> You:Some robots like you told me you have to buy gold, silver or stocks.
DialoGPT: I think my wallet is empty.
Như bạn có thể thấy, bây giờ nó đã tốt hơn nhiều, hãy thoải mái tinh chỉnh temperature
và top_k
các thông số và xem liệu nó có thể cải thiện nó hay không.
Lấy mẫu hạt nhân hoặc lấy mẫu Top-p chọn từ các từ nhỏ nhất có thể có xác suất tích lũy vượt quá tham số p
chúng tôi đặt.
Dưới đây là một ví dụ sử dụng lấy mẫu Top-p:
# chatting 5 times with nucleus sampling & tweaking temperature
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_p=0.95,
top_k=0,
temperature=0.75,
pad_token_id=tokenizer.eos_token_id
)
#print the output
output = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
print(f"DialoGPT: {output}")
Chúng tôi đặt top_k
để 0
tắt lấy mẫu Top-k, nhưng bạn có thể sử dụng cả hai phương pháp có xu hướng hoạt động tốt hơn. Đây là một cuộc trò chuyện:
>> You:How can I be rich fast?
DialoGPT: Inflation and free money
>> You:lol, but that takes time, I need fast money.
DialoGPT: Your post makes no sense. You just need a lot of money to be rich fast
>> You:Ok how to get a lot of money?
DialoGPT: Buy gold and then trade it for money.
>> You:Hmm, I got your point, thanks.
DialoGPT: No problem. You have to have money to buy gold, but its only good for trading it.
>> You:Yeah, I understand, thank you so much.
DialoGPT: Ok, let me know if you need help
Giờ đây, chatbot rõ ràng có ý nghĩa trong nhiều trường hợp.
Bây giờ, hãy thêm một số mã để tạo nhiều hơn một phản hồi chatbot và sau đó chúng tôi chọn phản hồi nào sẽ bao gồm trong đầu vào tiếp theo:
# chatting 5 times with nucleus & top-k sampling & tweaking temperature & multiple
# sentences
for step in range(5):
# take user input
text = input(">> You:")
# encode the input and add end of string token
input_ids = tokenizer.encode(text + tokenizer.eos_token, return_tensors="pt")
# concatenate new user input with chat history (if there is)
bot_input_ids = torch.cat([chat_history_ids, input_ids], dim=-1) if step > 0 else input_ids
# generate a bot response
chat_history_ids_list = model.generate(
bot_input_ids,
max_length=1000,
do_sample=True,
top_p=0.95,
top_k=50,
temperature=0.75,
num_return_sequences=5,
pad_token_id=tokenizer.eos_token_id
)
#print the outputs
for i in range(len(chat_history_ids_list)):
output = tokenizer.decode(chat_history_ids_list[i][bot_input_ids.shape[-1]:], skip_special_tokens=True)
print(f"DialoGPT {i}: {output}")
choice_index = int(input("Choose the response you want for the next input: "))
chat_history_ids = torch.unsqueeze(chat_history_ids_list[choice_index], dim=0)
Tôi đã thiết lập num_return_sequences
để 5
trả lại 5 câu cùng một lúc, chúng ta phải chọn một câu sẽ có trong chuỗi tiếp theo. Dưới đây là làm thế nào nó đi:
>> You:Hello, friend.
DialoGPT 0: Hey there!
DialoGPT 1: I am your friend, and I am also your friend.
DialoGPT 2: Hello. :
DialoGPT 3: Hiya! How are you?
DialoGPT 4: Hello. I like your username.
Choose the response you want for the next input: 3
>> You:Fine, thanks, what about you?
DialoGPT 0: Good. Not much to do.
DialoGPT 1: Not much, you?
DialoGPT 2: Fine, thanks.
DialoGPT 3: I'm okay, thank you for asking.
DialoGPT 4: I'm fine too.
Choose the response you want for the next input: 2
>> You:Can you tell me how can I get rich quickly?
DialoGPT 0: Yes, I can!
DialoGPT 1: Yes, just look up how to get rich on Google.
DialoGPT 2: Just keep doing your thing. You'll get rich.
DialoGPT 3: No, I can't.
DialoGPT 4: no, i have no money
Choose the response you want for the next input: 1
>> You:Yeah, but I thought you have an answer...
DialoGPT 0: I'm getting married in the morning.
DialoGPT 1: How do you get rich?
DialoGPT 2: I think there are many good answers, but I could send you one, if you want.
DialoGPT 3: I will, thanks!
DialoGPT 4: I thought you have an answer.
Choose the response you want for the next input: 2
>> You:Yes, please send me.
DialoGPT 0: You can send me link.
DialoGPT 1: I am very interested
DialoGPT 2: I sent you a PM
DialoGPT 3: I'll send you a PM
DialoGPT 4: I am always interested in new ideas.
Choose the response you want for the next input: 2
Và bạn hiểu rồi, tôi hy vọng hướng dẫn này đã giúp bạn cách tạo văn bản trên DialoGPT và các mô hình tương tự. Để biết thêm thông tin về cách tạo văn bản, tôi thực sự khuyên bạn nên đọc hướng dẫn Cách tạo văn bản bằng Transformers .
Tôi sẽ để bạn điều chỉnh các thông số để xem liệu bạn có thể làm cho bot hoạt động tốt hơn hay không.
Ngoài ra, bạn có thể kết hợp điều này với các hướng dẫn chuyển văn bản thành giọng nói và chuyển lời nói thành văn bản để xây dựng một trợ lý ảo như Alexa , Siri , Cortana , v.v.
#python #ai #chatbot